Eu tenho uma tabela com 20 milhões de linhas e cada linha tem 3 colunas: time
, id
e value
. Para cada id
e time
, há um value
para o status. Quero saber os valores do último e dos próximos períodos para um determinado time
e id
, e tenho a seguinte consulta para obter os valores:
update a1
set a1.value_last = b1.value,
a1.value_next = c1.value
from tab1 a1
left join tab1 b1
on a1.id = b1.id
and a1.period = b1.period + 1
left join tab1 c1
on a1.id = c1.id
and a1.period = c1.period - 1
Parece que a consulta demora uma eternidade e o arquivo de log aumentou em mais de 10 GB. Eu estou querendo saber qual é a maneira mais eficiente de escrever esta consulta? Sei que usar o índice acelerará o processo de junção, mas como posso reduzir o registro?
Estou usando o SQL Server 2016 no Win10 64 bits.
índice no id, ponto
ou apenas use uma visualização - isso pode surpreendê-lo
para registro
, é necessário esperar que o valor não seja nulo ou isso ficará confuso
Se entendi a pergunta, você não precisa atualizar nada - é apenas o meio que você está usando para oferecer suporte a uma instrução SELECT que não é mostrada aqui.
Nesse caso, isso deve levá-lo até lá sem precisar de uma ATUALIZAÇÃO:
Este código funcionará no SQL Server 2012 (nível de compatibilidade 110) e superior.
Com o
PARTITION BY id
como parte das funções LAG e LEAD, lembre-se de que a primeira linha da partição terá NULL para seuvalue_last
(porque não há linha anterior na partição) e a última linha da partição terá NULL para seuvalue_next
( porque não há próxima linha na partição). Se você quiser alterá-los para algum outro valor - talvez zero - esse valor vai onde o NULL está naLAG([value], 1, NULL)
parte do código.Ao usar essas funções de janela (como @Jorriss sugere), você está eliminando a necessidade de uma instrução UPDATE e o registro que vem com ela.
Dê uma olhada em SQL Server Window Functions, especificamente
LAG
eLEAD
. Essas funções permitem que a consulta obtenha dados no conjunto de resultados sem junções automáticas. Aqui está um exemplo do despejo de dados StackOverflow.LAG (p.ID, 1)
irá procurar oID
na linha anterior.LEAD (p.ID, 1)
irá procurar oID
na próxima linha.Você notará que, se não houver um valor encontrado, ele retornará um
NULL
.