Eu tenho uma consulta como
SELECT COUNT(*) FROM Foo Where Bar = 1 AND Baz = 2
a tabela tem 12934600 registros dos quais 1000001 correspondem a esse predicado
Olhando para as estatísticas de consulta que vejo
(1 linha(s) afetada(s) Tabela 'Foo'. Contagem de varredura 1, leituras lógicas 1863 , leituras físicas 0, leituras antecipadas 0, leituras lógicas lob 0, leituras físicas lob 0, leituras antecipadas lob 0.
(1 linha(s) afetada(s))
Tempos de execução do SQL Server: tempo de CPU = 250 ms, tempo decorrido = 503 ms.
Observando o plano de consulta, 80% do tempo é gasto em uma busca de índice nas colunas Bar e Baz e 20% na agregação do resultado.
Existe uma maneira de acelerar isso e, em caso afirmativo, como? Também gostaria de entender quais componentes de hardware têm uma grande influência aqui CPU ou disco IO ou velocidade do barramento.
Lembre-se que o plano de consulta mostra uma estimativa de custo que não é igual ao tempo . Os valores de custo estimados são uma agregação sem unidade de CPU, memória e E/S, não quanto tempo cada operação leva para ser executada. Também tenha em mente que os valores de custo são estimativas mesmo em um plano de execução "real".
O maior gargalo para esta e a maioria das outras operações do SQL Server é o disco IO. Seu exemplo
STATISTICS
parece ser de uma segunda execução, pois não há leituras físicas, portanto, você vê uma CPU mais alta que é usada para a agregação/classificação.Você pode acelerar essa consulta específica com um índice filtrado, se seu
WHERE
predicado for consistente (ou seja, sempreBar = 1 AND Baz = 2
).Caso contrário, não conheço uma maneira de acelerá-lo além de algo mais drástico, como uma exibição indexada.
Para o SQL Server 2008, um índice filtrado que corresponda à cláusula where deve acelerar isso.
Se você deseja ter parâmetros, não constantes, uma exibição indexada pode ter isso pré-calculado com um GROUP BY em Bar e Baz
Você também pode encontrar algum grau de bloqueio.
Quando eu testo a
COUNT(*)
em uma tabela com páginas extraídas do cache, parece haver muito mais limite de CPU do que seus resultados mostram (mais como 90% do tempo de CPU do que 50%).Você pode tentar
NOLOCK
e ver se isso melhora as coisas. Em caso afirmativo, você precisará determinar se oCOUNT
retorno provavelmente é suficientemente preciso para seus propósitos.