Проблема производительности при обновлении представления (используя вместо триггера) через курсор в Sql Server 2005 - PullRequest
2 голосов
/ 27 апреля 2009

У меня есть представление V в базе данных D1, для которого определен триггер обновления U, обновляющий три таблицы T1, T2 и T3 в базе данных D2. Эти три таблицы содержат 0,75, 6,0 и 4,5 миллиона записей. Версия Sql Server - 9.0.3042, версия для разработчиков.

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

UPDATE V
SET cust_task_id = 11975628
WHERE custno = '0319607'

Однако, когда я выпускаю следующую партию, она занимает одну минуту и ​​12 секунд:

DECLARE CURSOR c
FOR SELECT custno, cust_task_id FROM V WHERE custno = '0319607'
FOR UPDATE OF cust_task_id

OPEN c
    FETCH NEXT FROM c

    UPDATE V
    SET cust_task_id = 11975628
    WHERE CURRENT OF c    
CLOSE c
DEALLOCATE c

Когда я использую одни и те же базы данных (в отношении определения и количества записей) и одни и те же операторы обновления в версии Sql Server 2000 (8.0.2039, Standard Edition), обе партии возвращаются в течение одной секунды!

Когда вы смотрите на планы запросов пакетов курсоров в двух версиях Sql Server, вы видите, что план 2005 года использует сканирование индекса по таблицам T1, T2 и T3, тогда как план 2000 года использует индекс стремится. Это объясняет разницу в производительности.

Я пытался sp_updatestats в базах данных 2005 года, но это не помогло.

Кто-нибудь знает, как заставить пакет 2005 курсора работать так, как он должен?

Заранее спасибо, что нашли время разобраться в этом вопросе.

Привет,

Лекс Вербик

Ответы [ 2 ]

2 голосов
/ 27 апреля 2009

Чтобы решить вашу непосредственную проблему, у нас была похожая проблема в SQL 2000 некоторое время назад с курсором, использующим источник данных, который сам был изменен во время цикла курсора (в этом случае вы выбираете из V, а также обновляете V). Из памяти (и было бы хорошо получить подтверждение) источник данных для курсора был либо обновлен, либо обновлен таким образом, чтобы поддерживать источник данных в актуальном состоянии с внесенными изменениями.

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

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

1 голос
/ 27 апреля 2009

Провели ли вы различие в схемах для версии 2000 и версии 2005 года.

Если версия 2005 сканирует, а не ищет, может показаться, что вам не хватает индекса в одном из столбцов столяра, который используется для создания VIEW

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