Estou comparando duas consultas no SQL Server 2012. O objetivo é usar todas as informações pertinentes disponíveis no otimizador de consultas ao escolher a melhor consulta. Ambas as consultas produzem os mesmos resultados; o número máximo de pedidos para todos os clientes.
A limpeza do buffer pool foi feita antes de executar cada consulta com FREEPROCCACHE e DROPCLEANBUFFERS
Usando as informações fornecidas abaixo, qual consulta é a melhor escolha?
-- Query 1 - return the maximum order id for a customer
SELECT orderid, custid
FROM Sales.Orders AS O1
WHERE orderid = (SELECT MAX(O2.orderid)
FROM Sales.Orders AS O2
WHERE O2.custid = O1.custid);
-- Query 2 - return the maximum order id for a customer
SELECT MAX(orderid), custid
FROM Sales.Orders AS O1
group by custid
order by custid
TEMPO ESTATÍSTICO
Consulta 1 TEMPO ESTATÍSTICO: tempo de CPU = 0ms, tempo decorrido = 24 ms
Consulta 2 TEMPO ESTATÍSTICO: tempo de CPU = 0 ms, tempo decorrido = 23 ms
ESTATÍSTICAS IO
Consulta 1 ESTATÍSTICA IO: Tabela 'Pedidos'. Contagem de varreduras 1, leituras lógicas 5, leituras físicas 2, leituras antecipadas 0, leituras lógicas lob 0, leituras lógicas lob 0, leituras físicas lob 0, leituras antecipadas lob.
Consulta 2 ESTATÍSTICAS IO: Tabela 'Pedidos'. Contagem de varreduras 1, leituras lógicas 4, leituras físicas 1, leituras antecipadas 8, leituras lógicas 0, lob leituras físicas 0, leituras físicas lob 0, leituras antecipadas lob 0.
Planos de Execução
Propriedades SELECT Consulta 1
Propriedades SELECT Consulta 2
Conclusões:
Consulta 1
- Custo do lote 48%
- Leituras lógicas 5
- Leituras físicas 2
- Leituras antecipadas: 0
- Tempo de CPU: 0ms
- Tempo decorrido 24ms
- Custo estimado da subárvore: 0.0050276
- CompileCPU: 2
- CompileMemory: 384
- CompileTime: 2
Consulta 2
- Custo do lote 52%
- Leituras lógicas 4
- Listas Physcial 1
- Leituras de leitura antecipada: 8
- Tempo de CPU 0
- Tempo decorrido 23ms
- Custo estimado da subárvore: 0.0054782
- CompileCPU: 0
- CompileMemory: 192
- CompileTime: 0
Pessoalmente, embora a Consulta 2 tenha um custo de lote mais alto, de acordo com o plano gráfico, acho mais eficaz que a Consulta 1. Isso porque a consulta 2 requer leituras menos lógicas, tem um tempo decorrido um pouco menor, os valores compilecpu, compilememory e compiletime são mais baixo. as leituras de read-ahead são 8 para a consulta 2 e 0 para a consulta 1.
Atualização 12:03
Definição de índice clusterizado
ALTER TABLE [Sales].[Orders] ADD CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED
(
[orderid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
Índice não clusterizado idx_nc_custid
CREATE NONCLUSTERED INDEX [idx_nc_custid] ON [Sales].[Orders]
(
[custid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO