Яков Сироткин (yakov_sirotkin) wrote,
Яков Сироткин
yakov_sirotkin

Как разрастаются хранимые процедуры

Все знают, что иногда хранимые процедуры дают очень существенный прирост производительности. Поэтому очень легко на старте проекта вместо обычного SELECT сделать хранимую процедуру. Пожалуй, тут нельзя говорить о преждевременной оптимизации, это решение уровня «а вдруг».

Если результаты запроса показываются пользователям, то вполне возможно, что будут происходить частые изменения: добавить колонку, отформатировать по другому, отсортировать то, отфильтровать это, какие-то экзотические хотелки. Конечно, придется делать JOIN с другими таблицами, но это не страшно. А ещё бывает очень удобно обернуть текущий запрос в SELECT * FROM (...) и потом ещё немного посортировать и пофильтровать. Также все знают про UNION, а если сделать UNION ALL, то потом можно ещё применить DISTINCT. В общем, процедура потихоньку разрастается, появляются новые входные параметры.

Но в хранимых процедурах нет ООП (это же процедуры!), нет паттернов проектирования — даже Builder. Нет поддержки рефакторинга Extract Method, даже подсветки неиспользуемых переменных нет. Однако, это никого не волнует — это ведь в Java методы должны умещаться на экран, а в хранимой процедуре может быть и 1000 строк, и больше. Зато на хранимую процедуру не надо писать Unit-тесты, для этого ведь нет инструментов. Впрочем, задача покрытия тестами процедуры на 1000 строк в принципе запредельно сложная.

Итого, мы получаем гигантскую процедуру, которая всего лишь генерирует сложный SELECT, но настройка отладки или записи в лог является проблемой. Становится понятно, что лучше написать на Java, но как убедиться, что новая реализация соответствует текущей? К счастью, в случае SELECT можно просто сравнить старый и новый результат на большом количестве запросов, при этом наверняка вылезут разные интересные особенности и баги в старой реализации.

Но переписать на Java всегда сложно по тактическим причинам: сначала можно переписать за день, но требуемые прямо сейчас изменения можно сделать за час. А когда на внесение изменений будет требоваться день, на переписывание нужно будет потратить неделю. Изменения за неделю — переписывание за месяц. Дальше цепочка обрывается, потому что система становиться слишком сложной — если что-то добавить, то где-то что-то отвалится.

Есть три стратегии, чтобы вернуть разработку в нормальное русло. Во-первых, можно потихоньку уменьшать сложность хранимой процедуры: если у неё больше 10 параметров, то какие-то наверняка не используются. Какие-то вычисления тривиальным образом переносятся в Java. Во-вторых, можно честно переписать хранимую процедуру на Java, к этому методу приходится прибегать, если бизнесу нужны радикальные изменения и нет времени ждать. В-третьих, можно написать на wiki спецификацию и разработать эту функциональность с нуля. Такая спецификация легко пишется по новому коду в случае полного переписывания, но обычно бизнес не очень понимает, что происходит внутри хранимой процедуры.
Tags: java
Subscribe
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 10 comments