Criei a tabela big_table de acordo com seu esquema
create table big_table
(
updatetime datetime not null,
name char(14) not null,
TheData float,
primary key(Name,updatetime)
)
Em seguida, preenchi a tabela com 50.000 linhas com este código:
DECLARE @ROWNUM as bigint = 1
WHILE(1=1)
BEGIN
set @rownum = @ROWNUM + 1
insert into big_table values(getdate(),'name' + cast(@rownum as CHAR), cast(@rownum as float))
if @ROWNUM > 50000
BREAK;
END
Usando o SSMS, testei as duas consultas e percebi que, na primeira consulta, você está procurando o MAX do TheData e, na segunda, o MAX do updatetime
Assim, modifiquei a primeira consulta para obter também o MAX do tempo de atualização
set statistics time on -- execution time
set statistics io on -- io stats (how many pages read, temp tables)
-- query 1
SELECT MAX([UpdateTime])
FROM big_table
-- query 2
SELECT MAX([UpdateTime]) AS value
from
(
SELECT [UpdateTime]
FROM big_table
group by [UpdateTime]
) as t
set statistics time off
set statistics io off
Usando o tempo de estatística , recebo de volta o número de milissegundos necessário para analisar, compilar e executar cada instrução
Usando o Statistics IO , recebo informações sobre a atividade do disco
ESTATÍSTICAS TEMPO e ESTATÍSTICAS IO fornecem informações úteis. Como as tabelas temporárias usadas (indicadas pela mesa de trabalho). Além disso, quantas páginas lógicas lidas foram lidas, o que indica o número de páginas do banco de dados lidas no cache.
Ativei o plano de execução com CTRL + M (ativa o plano de execução atual) e depois executo com F5.
Isso fornecerá uma comparação das duas consultas.
Aqui está a saída da guia Mensagens
- Consulta 1
Tabela 'big_table'. Contagem de varreduras 1, leituras lógicas 543 , leituras físicas 0, leituras de read-ahead 0, leituras lógicas de lob 0, leituras físicas de lob 0, leituras físicas de lob 0, leituras de read-ahead de lob 0.
Tempos de execução do SQL Server:
tempo de CPU = 16 ms, tempo decorrido = 6 ms .
- Consulta 2
Tabela ' Mesa de trabalho '. Contagem de varreduras 0, leituras lógicas 0, leituras físicas 0, leituras de leitura antecipada 0, leituras lógicas de lob 0, leituras físicas de lob 0, leituras físicas de lob 0, leituras de leitura antecipada de lob 0.
Tabela 'big_table'. Contagem de varreduras 1, leituras lógicas 543 , leituras físicas 0, leituras de read-ahead 0, leituras lógicas de lob 0, leituras físicas de lob 0, leituras físicas de lob 0, leituras de read-ahead de lob 0.
Tempos de execução do SQL Server:
tempo de CPU = 0 ms, tempo decorrido = 35 ms .
Ambas as consultas resultam em 543 leituras lógicas, mas a segunda consulta tem um tempo decorrido de 35ms, sendo que a primeira possui apenas 6ms. Você também notará que a segunda consulta resulta no uso de tabelas temporárias no tempdb, indicadas pela palavra tabela de trabalho . Embora todos os valores da tabela de trabalho estejam em 0, o trabalho ainda foi realizado no tempdb.
Depois, há a saída da guia Plano de execução real ao lado da guia Mensagens
De acordo com o plano de execução fornecido pelo MSSQL, a segunda consulta que você forneceu tem um custo total de lote de 64%, enquanto a primeira custa apenas 36% do lote total, portanto, a primeira consulta exige menos trabalho.
Usando o SSMS, você pode testar e comparar suas consultas e descobrir exatamente como o MSSQL está analisando suas consultas e quais objetos: tabelas, índices e / ou estatísticas, se houver alguma que esteja sendo usada para satisfazer essas consultas.
Uma observação adicional a ter em mente quando o teste estiver limpando o cache antes do teste, se possível. Isso ajuda a garantir que as comparações sejam precisas e isso é importante quando se pensa em atividade do disco. Começo com DBCC DROPCLEANBUFFERS e DBCC FREEPROCCACHE para limpar todo o cache. Cuidado para não usar esses comandos em um servidor de produção realmente em uso, pois você forçará efetivamente o servidor a ler tudo do disco para a memória.
Aqui está a documentação relevante.
- Limpe o cache do plano com DBCC FREEPROCCACHE
- Limpe tudo do buffer pool com DBCC DROPCLEANBUFFERS
O uso desses comandos pode não ser possível, dependendo de como seu ambiente é usado.
Atualizado 10/28 12:46 pm
Correções na imagem do plano de execução e na saída de estatísticas.
getdate()
para fora do loop