Медленное ОБНОВЛЕНИЕ на SQL Server, даже когда записи не обновляются - PullRequest
2 голосов
/ 25 января 2012

Проблемы с блокировкой таблицы не подтверждены.

У меня есть оператор обновления, похожий на этот.

UPDATE table1 
SET table1.col1 = table2.col2 
FROM table1,table2
WHERE table1.id = table2.id

Это происходит вечно, даже если нет записей для обновления

, выполняющих запрос

SELECT * 
FROM table1,table2
WHERE table1.id = table2.id

мгновенно.

РЕШЕНИЕ НАЙДЕНО: Для чего бы то ни было, я включил «Включить фактический план выполнения», как было предложено, и рекомендовал 3 индекса, которых у меня не было, и теперь выполняю всю хранимую процедуру, которая работает с 190 операторами SQL.на столах с 16 миллионами строк менее чем за 1 минуту.Грация тому, кто это предложил.

Ответы [ 3 ]

6 голосов
/ 25 января 2012

На самом деле, вы обновляете каждую строку каждый раз. Вы должны добавить следующее к предложению where:

AND table1.col1 <> table2.col2

Возможно, вам понадобится добавить ISNULL оболочки для каждой стороны, если это поля, допускающие пустые значения

Что быстрее: читать книгу или писать над каждым словом в книге одно и то же точное слово? Тот факт, что вы пишете то же значение, что и исходное значение, не меняет того факта, что вы пишете значения.

Теперь, если у вас есть предложение where, отфильтровывающее записи с совпадающими значениями, и у вас все еще очень низкая производительность, то вероятным виновником будет слишком много индексов. Я предполагаю, что это не ваша проблема здесь ...

3 голосов
/ 25 января 2012

Можете ли вы использовать правильное соединение:

Update t
SET t.Col1 = t2.col2
FROM table1 t INNER JOIN
table2 t2 ON t.PK = t2.FK

После этого проверьте все дополнительные процессы, запущенные на этом сервере.

Используйте SQL Profiler, чтобы увидеть, что происходит за кулисами. Проверьте, не запущены ли какие-либо необычные процессы / задания, которые могут повлиять на обновление.

Это занимает вечность, даже если нет записей обновление

Это также как уже упоминалось, обновляя все, пока существует соединение, нет условия, при котором оно не может не обновляться. Обновляется каждая строка таблицы, значение col1 из таблицы t заменяется значением col2 из t2.

Также см. Раздел комментариев:

@ Барт - и ты понимаешь, что обновляешь 16 миллионов кортежей, верно? В вашем запросе ничего не указано иначе, значение col1 перезаписывается col2, даже если col1 и col2 содержат одно и то же значение. Вы следует сделать что-то с эффектом WHERE col2 <> col1, чтобы вы обновляются только значения, отличающиеся

2 голосов
/ 25 января 2012
Update t 
SET t.Col1 = t2.col2 
FROM table1 t 
INNER JOIN table2 t2 ON t.PK = t2.FK 
where t.Col1 <> t2.col2 

Это то, что вы должны бежать. SQL Server не заботится, что значения совпадают, он обновляет их в любом случае.

И я с @JonH, эти имплицитные объединения являются антипаттерном sql и были заменены чем-то лучшим 20 лет назад, нет никакого оправдания тому, чтобы писать запросы таким образом. Вы получаете случайные перекрестные соединения, и их сложнее поддерживать. Кроме того, в SQL Server неявные левые и правые объединения устарели и все равно никогда не работали правильно. Поэтому, если вам нужно перейти к левому соединению в обслуживании, вам нужно будет изменить весь запрос, потому что объединение имплицитных и явных объединений может дать вам неправильные ответы.

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