Что быстрее в SQL, While loop, Recursive Stored proc или Cursor?

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

Ответы

Ответ 1

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

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

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

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

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

  • Использование подхода на основе набора (внутренние выбирает, объединяет, объединяет и т.д.)
  • Использование CTE (прозрачный и управляемый для опытного пользователя, бит теневой для новичков)
  • Использование операторов потока управления (если, while...)
  • Использование курсоров (процедурный код, легко следовать)

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

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

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

Ответ 2

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

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

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

Ответ 7

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

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