Одним очевидным улучшением было бы избавление от цикла WHILE
и построчной обработки. Если вы не делаете это в явной транзакции, вам нужно будет дождаться завершения 10 отдельных коммитов, и общий объем требуемой работы в любом случае будет больше, как показано в статистике ниже.
NB. Однако я не утверждаю, что мой запрос не может быть улучшен. Возможно, вы сможете настроить подход «необычного обновления» для своих нужд и сделать это, например, с помощью одного сканирования данных.
create table t (
column_id int identity(1,1) primary key,
column_data float,
column_stdev float)
insert into t (column_data)
select top 10 CHECKSUM(newid()) from sys.objects
SET STATISTICS IO ON
UPDATE t
SET column_stdev = (SELECT stdev(t2.column_data)
FROM t t2
WHERE t2.column_id BETWEEN t.column_id AND t.column_id + 2)
/*Table 't'. Scan count 11, logical reads 42, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 23, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.*/
declare @i int
set @i=1
while @i < 11
begin
update t
set column_stdev = (select stdev(column_data) from t
where column_id between @i and @i+2)
set @i=@i+1
end
/* (Aggregated the 10 results)
Table 't'. Scan count 20, logical reads 240, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 10, logical reads 230, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.*/