Estou tentando escrever uma consulta eficiente para excluir blocos de dados. Para esse fim, esperava evitar uma varredura de índice usando a chave primária para obter os registros mais antigos. No entanto, estou vendo alguns resultados inesperados retornados.
eu esperava isso
SELECT TOP 15 OrderID FROM [Order]
Me daria os 15 registros mais antigos porque eu poderia confiar no incremento da chave primária e, portanto, a ordem de armazenamento seria baixa para alta na tabela.
No entanto, isso retorna um conjunto de resultados diferente
SELECT TOP 15 OrderID FROM [Order] ORDER BY DateCreated ASC
O que parece ser uma maneira mais precisa, mas mais cara, de obter o resultado de que preciso.
Confusamente, isso
SELECT TOP 15 * FROM [Order]
Fornece um conjunto diferente de OrderID s (PK) para este
SELECT TOP 15 OrderID FROM [Order]
Entendo que http://msdn.microsoft.com/en-gb/library/ms189463.aspx explica que o pedido não pode ser garantido sem uma cláusula ORDER BY, mas esperava que o PK fizesse o pedido para mim e não pode explicar as diferenças entre os duas últimas cláusulas selecionadas.
Dê uma olhada nos planos. Quando você o usa
SELECT *
, provavelmente usa o índice clusterizado e, quando deseja apenas uma coluna, talvez haja um índice mais fino para usar.Não "espere" uma determinada ordem. Se você não disser ao SQL Server como fazer o pedido, ele usará a maneira mais eficiente possível e isso pode mudar devido a provavelmente mais de 20 fatores.
Se você quer uma certa ordem, DIGA. Por favor, leia o nº 3 aqui:
Além disso, esta postagem de Michael Swart pode ser uma leitura interessante:
Se você deseja que sua segunda consulta seja mais eficiente, considere a criação de um índice em
DateCreated
(você pode querer incluirOrderID
- não tem certeza da estrutura de índice atual).Para seu objetivo real de excluir
n
linhas por vez, as mais antigas primeiro e assumindo queOrderID
é umaIDENTITY
coluna (portanto, a data de criação do pedido deve se alinhar aproximadamente com isso), por que não usar esta abordagem (com base nesta ótima postagem no blog, também de Michael Swart ):Para minimizar o impacto no log, você pode adicionar alguma lógica adicional, da minha postagem no blog Quebrar grandes operações de exclusão em partes . Quanto ao
dbo
prefixo, consulte Maus hábitos para chutar : Evitando o prefixo do esquema .