Что происходит, когда вы забудете закрыть и освободить курсор? - PullRequest
29 голосов
/ 07 марта 2012

Оставление курсора открытым считается плохой практикой. Но что на самом деле происходит, когда вы забудете закрыть и / или освободить его? Как это влияет на SQL Server, соединение / сеанс? Существуют ли различия в последствиях для запросов, хранимых процедур и триггеров, использующих курсоры?

Ответы [ 3 ]

30 голосов
/ 07 марта 2012

Это зависит от того, объявили ли вы курсор локально или глобально (и какое значение по умолчанию в вашей среде - значение по умолчанию является глобальным, но вы можете изменить его).

Если курсор является глобальным, он может остаться«жив» в SQL Server до тех пор, пока последний фрагмент кода не будет затронут в области, в которой он был создан.Например, если вы вызываете хранимую процедуру, которая создает глобальный курсор, а затем вызываете 20 других хранимых процедур, курсор будет жить, пока эти другие 20 хранимых процедур работают, до тех пор, пока вызывающая сторона не выйдет из области видимости.Я верю, что он останется живым на уровне сеанса, а не на уровне соединения, но не проверил это полностью.Если курсор объявлен как локальный, то он должен оставаться в области видимости только для текущего объекта (но опять же, это теоретически, и я не провел обширных тестов памяти низкого уровня для подтверждения).

Однако общая концепция должна заключаться в следующем: когда вы закончите с чем-то, скажите так.

Чтобы сделать мои курсоры максимально эффективными, я всегда использую следующие объявления:

DECLARE c CURSOR
  LOCAL STATIC FORWARD_ONLY READ_ONLY
  FOR SELECT ...

Я также слышал, что могут быть проблемы с памятью, если вы только CLOSE или только DEALLOCATE, поэтому я всегда делаю и то, и другое:

CLOSE c;
DEALLOCATE c;

Однако сколько курсоров делаетУ вас есть где очистка этого синтаксиса является проблемой?Если у вас есть сотни курсоров в вашей системе, это, безусловно, красный флаг для меня.

РЕДАКТИРОВАТЬ

В качестве дополнения, я просто хочу уточнить, что курсоры ви сами по себе не плохие.Однако их часто злоупотребляют и злоупотребляют - они реализуются в тех случаях, когда может быть реализовано более эффективное решение на основе множеств , но человек, которому поручено написать запрос, может думать только процедурно.Несколько случаев, когда курсоры имеют смысл:

  • Промежуточные суммы.В моем тестировании курсоры уничтожают все решения, основанные на предыдущих версиях SQL 2012 (по крайней мере, те, которые задокументированы и поддерживаются. 0.
  • Различные административные задачи, например, вызов хранимой процедуры для каждой строки в таблице или для каждой таблицы.или базы данных.
  • Когда альтернатива на основе множеств чрезвычайно сложна или задача одноразовая.
6 голосов
/ 06 августа 2014

«Переменная курсора не должна быть явно освобождена.Переменная неявно освобождается, когда выходит из области видимости. ”

Ссылка: http://msdn.microsoft.com/en-us/library/ms188782.aspx

6 голосов
/ 07 марта 2012

Не закрытие курсора будет держать блокировки активными, если он удерживает строки, в которых он расположен.Даже после закрытия ссылка сохраняется на структуры данных, которые использует курсор, хотя (так что ее можно открыть заново). Эти структуры специфичны для SQL-сервера (поэтому это не просто пространство памяти или дескрипторы или около того) и зависят от того, какой курсор на самом делено это обычно будут временные таблицы или наборы результатов запроса.

Отказ от AFAIK не связан только с производительностью.Вышеупомянутые ресурсы останутся распределенными и, таким образом, окажут негативное влияние на производительность сервера.

выделенные ресурсы из (открытых или закрытых, но не освобожденных) курсоров будут выделяться до тех пор, пока сеанс (или соединение) не будет закрыт

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