Что быстрее в SQL, в то время как цикл, рекурсивный сохраненный процесс или курсор? - PullRequest
21 голосов
/ 11 июня 2010

Что быстрее в SQL, в то время как цикл, рекурсивный сохраненный процесс или курсорЯ хочу оптимизировать производительность в нескольких местах хранимой процедуры.Код, который я оптимизирую, форматирует некоторые строки для вывода в файл.

Ответы [ 7 ]

18 голосов
/ 11 июня 2010

Я предполагаю, что вы используете SQL Server.

Прежде всего, как кто-то сказал в операторах, рекурсивные хранимые процессы, хотя и возможны, не являются хорошей идеей в SQL Server из-за размера стека. Итак, любая глубоко рекурсивная логика сломается. Однако, если у вас есть 2-3 уровня вложенности в лучшем случае, вы можете попробовать использовать рекурсию или CTE , что также немного рекурсивно (SQL Server 2005 и выше). Как только вам удастся обернуть голову вокруг CTE, это очень полезная техника. Я не измерял, но у меня никогда не было проблем с производительностью в тех немногих местах, где я использовал CTE.

С другой стороны, курсоры - это большие проблемы с производительностью, поэтому я ( и половина интернета ) рекомендовал бы не использовать их в коде, который часто вызывается. Но так как курсоры представляют собой более классическую структуру программирования, похожую на foreach в C #, некоторые люди считают, что проще смотреть, понимать и поддерживать код SQL, который использует курсоры для манипулирования данными, по сравнению с каким-то запутанным чудовищным множественным SQL так что это не самая плохая идея использовать их в коде, который будет вызываться время от времени.

Говоря о while, он также переносит мышление программирования с основанного на множестве на основанное на процедурах мышление, поэтому, хотя оно относительно быстрое и не потребляет много ресурсов, оно все равно может значительно увеличить количество данных. операторы манипуляции, выдаваемые вами самой базе данных.

Подводя итог, если бы мне нужно было создать сложный хранимый процесс, где производительность превыше всего, я бы попробовал:

  1. Использование подхода на основе множеств (внутренние выборки, объединения, объединения и т. Д.)
  2. Использование CTE (понятное и управляемое для опытного пользователя, немного затененное для начинающего)
  3. Использование операторов потока управления (если, в то время как ...)
  4. Использование курсоров (процедурный код, легко следовать)

в таком порядке.

Если код используется гораздо реже, я, вероятно, переместлю 3 и 4 до 1 и 2, но, опять же, только для сложных сценариев, которые используют много таблиц и множество отношений. Конечно, YMMV, так что я бы протестировал любую процедуру, которую я делаю в реальном сценарии, чтобы реально измерить производительность, потому что мы можем говорить, пока мы не поседели, что это быстро и медленно, но пока Вы получаете реальные измерения, и нет никакого способа определить, улучшают или ухудшают изменения.

И, не забывайте, код работает так же быстро, как ваши данные. Нельзя заменить хорошую индексацию.

9 голосов
/ 11 июня 2010

D) Ничего из перечисленного.

Метод на основе множеств почти всегда будет самым быстрым.Не зная, какой у вас реальный код (или близкое приближение), трудно сказать, возможно ли это или какой метод будет наиболее быстрым.

Лучше всего проверить все возможные методыпосмотрите, какой из них действительно самый быстрый.

4 голосов
/ 11 июня 2010

Если вы хотите улучшить производительность, вам нужно взглянуть на операции на основе SET.Хотя цикл и курсор это в основном одно и то же.SQL работает в SET, это не процедурный язык, используйте его так, как он предназначен

3 голосов
/ 11 июня 2010

Взгляните на Курсоры и как их избежать , который даст вам идеи о том, как заменить курсоры операциями на основе SET

1 голос
/ 11 июня 2010

В блоге есть раздел из трех частей о курсорах, который стоит прочитать, если у вас есть время.Я также избегаю их, как чумы, но этот блог заставил меня увидеть их в ином свете ... ну ... я немного жалею их сейчас, но все равно не буду их использовать!

Правда окурсоры

1 голос
/ 11 июня 2010

Рекурсивная хранимая процедура, вероятно, будет самой медленной, в то время как цикл и курсоры не являются взаимоисключающими.Операции с курсором выполняются довольно быстро (IME), но я когда-либо использовал их только из внешнего кода (не SQL).Другие постеры верны, если вы сможете выполнять свою обработку ориентированным на наборы образом, вы получите наилучшую производительность.

0 голосов
/ 11 июня 2010

Вы еще не знаете, но хотите прочитать эту книгу.

http://www.amazon.com/Refactoring-SQL-Applications-Stephane-Faroult/dp/0596514972

...