2009-07-14 4 views
1
update auditdata set TATCallType='12',TATCallUnit='1' from auditdata auditdata 
     inner join Auditdata_sms_12 a_sns 
     on auditdata.ID = a_sns.id 

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

, что неправильно в этом

Auditdata.ID является первичным ключом ..

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

+1

Какого СУБД? Насколько велики таблицы? Это только что началось в существующем запросе, или это новый запрос? –

+0

- Какой тип данных является вашим основным ключом? - Какие индексы у вас есть на этой таблице? –

+0

Насколько велика таблица? Если это 100 000 000 строк, и он должен обновлять каждую строку, не имеет значения, какие индексы у вас есть: это займет некоторое время. Таблица – Eric

ответ

1

Глядя на ваш комментарий, основная таблица содержит меньше строк, чем таблица темпа.

Попробуйте использовать EXISTS пункт (или в каком-то смысле, уменьшить сравнение с меньшим количеством строк (то есть 1500000)

update auditdata set TATCallType='12',TATCallUnit='1' 
from auditdata auditdata 
WHERE EXISTS 
(SELECT id from Auditdata_sms_12 a_sns WHERE a_sns.id = auditdata.ID) 

Идея заключается в том, чтобы ограничить сравнения

EDIT:. AuditdataSMS12 должны иметь индекс на ID, чтобы иметь возможность получить ряд быстро. То есть таблица на самом деле вы ищете для данного ID.

+0

хорошо я буду проверить его – John

+0

ой я действительно sorry..the основная таблица содержит 15000000 и временную таблицу содержат 3500000 – John

+0

hmmm. Я все еще думаю, что вам понадобится индекс в таблице temp - потому что вы запрашиваете его, и использование предложения EXISTS должно уменьшить сравнение по сравнению с внутренним соединением (если в таблице temp для данного ID в главной таблице указано более 1 строки в таблице temp) , – shahkalpesh

0

Обновлено я понял, прочитав первоначальный запрос еще раз, что вы не обновляют поле первичного ID, но 2 других полей данных. Пожалуйста, перечитайте первое заявление моего ответа и прокомментируйте его. Сожалею.

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

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

+0

Если вы обновите столбец в кластерном индексе, он физически переместит запись (по крайней мере, на SQL Server). Вот почему вы не вставляете ряд строк с вкрапленными значениями PK. Очевидно, что для многих обновлений это вызывает множество проблем. Однако OP не обновляет PK здесь, поэтому он не будет кластеризованным индексом. – Eric

+0

Да в моей исходной таблице ID является первичным ключом определяется как кластерный индекс не триггер не используется – John

+0

то, что я должен сделать, чтобы поститься SQL Query – John

0

Как долго просто выбрать (например,

select id from auditdata auditdata 
    inner join Auditdata_sms_12 a_sns 
    on auditdata.ID = a_sns.id 

) взять и сколько записей оно найдет?

Если сервер Sql должен прочитать все 5 миллионов записей или обновить миллион записей, а на нем недостаточно памяти или достаточно аппаратного обеспечения, возможно, вас не будет с запросом.

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

2

Здесь есть пара вещей.

Во-первых, выражение SQL выглядит сломанным. Предложение «FROM» в обновлении предназначено для использования в качестве обновления JOIN'd. Поскольку вы обновляете строки с жестко закодированными значениями, вам не нужно это делать.

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

Как проверка работоспособности, я бы сделал две вещи. Один, только обновить строки, которые еще не имеют установленных условий.Многие продукты СУБД с радостью будут выполнять операции ввода/вывода на физическом диске для строки, которая не изменяется (хотя многие этого не делают). Попробуйте с лимитом.

Два, примените обновление небольшими партиями. Это может реально помочь с конфликтом журналов и с более медленными дисками.

Так, что-то вроде следующее сначала попробовать:

UPDATE auditdata 
    SET TATCallType = '12' 
    , TATCallUnit = '1' 
    FROM auditdata 
WHERE TATCallType <> '12' 
    AND TATCallUnit <> '1' 
    AND EXISTS(SELECT * 
       FROM Auditdata_sms_12 a_sns 
       WHERE a_sns.id = auditdata.ID) 

Если вы хотите сделать сетки в SQL Server это довольно легко:

SET ROWCOUNT 2000 

UPDATE ... 

(run continually in a loop via T-SQL or by hand until @@ROWCOUNT = 0) 

SET ROWCOUNT 0 
Смежные вопросы