Почему мой курсор SQL Server очень медленный? - PullRequest
3 голосов
/ 22 октября 2008

Я использую курсор в своей хранимой процедуре. Он работает с базой данных, которая содержит огромное количество данных. для каждого элемента в курсоре я делаю операцию обновления. Это занимает огромное количество времени, чтобы завершить. Почти 25мин. :( .. В любом случае я могу сократить время, затрачиваемое на это?

Ответы [ 6 ]

7 голосов
/ 22 октября 2008

Быстрый ответ - не использовать курсор. Самый эффективный способ обновить множество записей - использовать оператор обновления. Существует не так много случаев, когда вам нужно использовать курсор, а не оператор обновления, вам просто нужно уметь правильно писать оператор обновления.

Если вы опубликовали снимок своего SQL, вы можете получить некоторую помощь для достижения того, что вам нужно.

6 голосов
/ 22 октября 2008

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

  • Написать пользовательскую функцию и использовать ее в обновлении (вероятно, все еще медленно)
  • Поместить данные во временную таблицу и использовать их в ОБНОВЛЕНИИ ... ОТ:

Знаете ли вы о синтаксисе ОБНОВЛЕНИЕ ... ОТ? Это довольно мощно, когда все становится сложнее:

UPDATE
  MyTable
SET
  Col1 = CASE WHEN b.Foo = "Bar" THEN LOWER(b.Baz) ELSE "" END,
  Col2 = ISNULL(c.Bling, 0) * 100 / Col3
FROM
  MyTable 
  INNER JOIN MySecondTable AS b ON b.Id = MyTable.SecondId
  LEFT  JOIN ##MyTempTable AS c ON c.Id = b.ThirdId
WHERE
  MyTabe.Col3 > 0
  AND b.Foo NOT IS NULL
  AND MyTable.TheDate > GETDATE() - 10

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

1 голос
/ 22 октября 2008

Я бы избегал использования курсора и работал с представлениями или материализованными представлениями, если это возможно. Курсоры - это то, что Microsoft не сильно оптимизирует в SQL Server, потому что большую часть времени вам следует использовать более общий оператор SQL (SELECT, INSERT, UPDATE, DELETE), чем с курсором.

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

Вы не предоставляете много конкретной информации, поэтому все, что я могу сделать, это дать несколько общих советов.

0 голосов
/ 22 октября 2008

Можете ли вы опубликовать дополнительную информацию о типе обновления, которое вы делаете?

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

Но если у вас нет выбора, у вас нет выбора. Не могу сказать без подробностей.

0 голосов
/ 22 октября 2008

Синтаксис UPDATE ... FROM, упомянутый выше, является предпочтительным методом. Вы также можете выполнить подзапрос, например, следующий:

UPDATE t1
SET t1.col1 = (SELECT top 1 col FROM other_table WHERE t1_id = t1.ID AND ...)
WHERE ...

Иногда это единственный способ сделать это, так как каждое обновление столбца может зависеть от разных критериев (или разных таблиц), и может быть «наилучший вариант», который вы хотите сохранить, используя предложение order by.

0 голосов
/ 22 октября 2008

Обновляете ли вы те же данные, над которыми работает курсор?

Какой тип курсора? только вперед? статические? набор ключей? динамический?

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