2016-01-19 4 views
2

приведенные ниже запросы возвращают около 80К записей:Update с играя слишком долго

это select занимает около 2 секунд, чтобы вернуться:

select fs.fsID 
from datFS fs 
join datAE t2 
on fs.fsID= t2.fsID 
join @AllCompletedNotYetDeleted t1 
on fs.fsID=t1.fsID 
where DateSent < DATEADD(m, -6, GETDATE()) 

в то время как его update (с точно такой же соединения) является навсегда ... я должен останавливать его каждый раз, так что еще не закончено ...

update fs set fs.testrun = getdate() 
from datFS fs 
join datAE t2 
on fs.fsID= t2.fsID 
join @AllCompletedNotYetDeleted t1 
on fs.fsID=t1.fsID 
where DateSent < DATEADD(m, -6, GETDATE()) 

что я делаю неправильно?

+0

есть ли указатель на столе? –

+0

fsID - это первичный уникальный ключ в datFS. –

+1

Добавьте предложение 'order by' или' select count (*) 'для первого запроса. Время, чтобы вернуть первую запись, - это не время, чтобы вернуть все из них. –

ответ

0

Попробуйте это:

DECLARE @date datetime = getdate() 

update fs set fs.testrun = @date 
from datFS fs 
join datAE t2 
on fs.fsID= t2.fsID 
join @AllCompletedNotYetDeleted t1 
on fs.fsID=t1.fsID 
where DateSent < DATEADD(m, -6, @date) 

Вы будете вызывать функцию даты только один раз, а не для каждой строки вы обновление.

+0

Пожалуйста, объясните, как это может улучшить производительность. –

+0

Имеет смысл добавить индекс в DateSent? – JonH

+0

Добавление индекса помогло бы в этом случае, но это замедлит обновления в столбце DateSent в будущем. Я для индексации чаще всего повышаю производительность чтения, но это не всегда решение, поскольку оно замедляет обновления и вставки. –

1

Попробуйте один -

CREATE UNIQUE NONCLUSTERED INDEX ix ON dbo.datFS (DateSent, fsID) 
GO 

DECLARE @dt DATETIME = DATEADD(M, -6, GETDATE()) 

UPDATE fs 
SET fs.testrun = GETDATE() 
FROM datFS fs 
WHERE DateSent < @dt 
    AND fs.fsID IN (
     SELECT t1.fsID 
     FROM @AllCompletedNotYetDeleted t1 
     JOIN datAE t2 ON t1.fsID = t2.fsID 
    ) 
OPTION(RECOMPILE) 
0

Пожалуйста, запустите это и вывесить план выполнения
Причина топ-10 является просто дайте ему сделать и устранить журнал транзакций заполнения/замедленное как проблема
Вы НЕ хотите оставить с (NOLOCK) активно - это только для проверки блокировок

Я доверяю FSID является ПК на datAE ??

Объявить FSID, как ПК на @AllCompletedNotYetDeleted
Если это большое даже попробовать его как #temp оптимизатор
запроса может сделать плохо с настольным переменными

Перестроить индексы, если они разобщены

update fs 
set top (10) fs.testrun = getdate() 
from datFS fs with (rowlock) 
join datAE t2 with (nolock) 
    on fs.fsID = t2.fsID 
join @AllCompletedNotYetDeleted t1 
    on fs.fsID = t1.fsID 
where DateSent < DATEADD(m, -6, GETDATE()) 
0

Ответ на ваш вопрос заключается в том, что вы хотите индексы. Для этого запроса:

select fs.fsID 
from datFS fs join 
    datAE t2 
    on fs.fsID = t2.fsID join 
    @AllCompletedNotYetDeleted t1 
    on fs.fsID = t1.fsID 
where DateSent < DATEADD(month, -6, GETDATE()); 

Лучшие индексы (вероятно) datAE(fsID) и @AllCompletedNotYetDeleted(fsID). В SQL Server 2014 вы можете явно создать индекс для переменной таблицы. В более ранних версиях вы можете сделать это неявно, создав уникальное ограничение. Это полезно answer.

Индекс, включающий в себя DateSent, может оказаться полезным. Однако неясно, в какой таблице находится столбец, а условие where может выбирать так много строк, что индекс не будет использоваться.

Наконец, вы также должны проверить, не получаете ли вы дубликаты записей в select/update - такие дубликаты просто теряют время в обновлении.

Смежные вопросы