Что быстрее в SQL, цикле while, рекурсивной хранимой процедуре или курсоре? Я хочу оптимизировать производительность в нескольких местах хранимой процедуры. Код, который я оптимизирую, форматирует некоторые строки для вывода в файл.
Что быстрее в SQL, цикле while, рекурсивной хранимой процедуре или курсоре?
Ответы (7)
Я предполагаю, что вы используете SQL Server.
Прежде всего, как кто-то сказал в заявлениях, рекурсивные хранимые процедуры, хотя и возможны, не являются хорошей идеей в SQL Server из-за размера стека. Итак, любая глубоко рекурсивная логика сломается. Однако, если у вас в лучшем случае 2-3 уровня вложенности, вы можете попробовать использовать рекурсию или использовать CTE, который также немного рекурсивен (SQL Server 2005 и выше). Как только вам удастся разобраться с CTE, это станет чрезвычайно полезной техникой. Я не измерял, но у меня никогда не было проблем с производительностью в нескольких местах, где я использовал CTE.
С другой стороны, курсоры сильно снижают производительность, поэтому я (и половина интернета) рекомендовал бы не использовать их в часто вызываемом коде. Но поскольку курсоры представляют собой скорее классическую структуру программирования, похожую на foreach
в C#, некоторым людям проще смотреть, понимать и поддерживать код SQL, который использует курсоры для манипулирования данными, чем какое-то запутанное чудовище SQL с множественным внутренним выбором, поэтому не самая плохая идея использовать их в коде, который будет вызываться время от времени.
Говоря о while
, он также переносит мышление программирования с подхода, основанного на наборах, на подход, основанный на процедурах, поэтому, несмотря на то, что он относительно быстр и не потребляет много ресурсов, он все же может значительно увеличить количество операторов манипулирования данными, которые вы выдаете. сама база данных.
Подводя итог, если бы мне пришлось создать сложную хранимую процедуру, где производительность имеет первостепенное значение, я бы попробовал:
- Использование подхода на основе набора (внутренний выбор, объединение, объединение и т. д.)
- Использование CTE (понятно и понятно для опытного пользователя, немного сомнительно для новичка)
- Использование операторов управления потоком (if, while...)
- Использование курсоров (процедурный код, простой для понимания)
в этой последовательности.
Если код будет использоваться гораздо реже, я, вероятно, перенесу 3 и 4 перед 1 и 2, но, опять же, только для сложных сценариев, в которых используется много таблиц и много отношений. Конечно, YMMV, поэтому я бы протестировал любую процедуру, которую я делаю, в реальном сценарии, чтобы на самом деле измерить производительность, потому что мы можем говорить до посинения о том, что быстро, а что медленно, но пока вы получаете реальные измерения, невозможно сказать, улучшают ли изменения ситуацию или ухудшают ее.
И, не забывайте, скорость кода зависит от скорости ваших данных. Ничто не заменит хорошую индексацию.
Г) Ничего из вышеперечисленного.
Метод на основе набора почти всегда будет самым быстрым методом. Не зная, каков ваш фактический код (или близкое приближение), трудно сказать, возможно ли это или какой метод будет самым быстрым.
Лучше всего протестировать все возможные методы, которые у вас есть, и посмотреть, какой из них действительно самый быстрый.
Если вы хотите повысить производительность, вам нужно взглянуть на операции на основе SET, хотя циклы и курсоры в основном одно и то же. SQL работает в SET, это не процедурный язык, используйте его так, как он предназначен для использования
Рекурсивная хранимая процедура, вероятно, будет самой медленной, а цикл и курсоры не исключают друг друга. Операции с курсором довольно быстрые (IME), но я когда-либо использовал их только из внешнего (не SQL) кода. Другие плакаты верны, если вы можете выполнять обработку в соответствии с набором, вы получите наилучшую производительность.
Взгляните на Курсоры и как их избежать. заменить курсоры операциями на основе SET
В блоге есть статья из трех частей о курсорах, которую стоит прочитать, если у вас есть время. Я также избегаю их, как чумы, но этот блог заставил меня увидеть их в другом свете... ну... теперь я их немного жалею, но все равно не буду их использовать!
Вы еще не знаете, но хотите прочитать эту книгу.
https://rads.stackoverflow.com/amzn/click/com/0596514972