Creé la tabla big_table de acuerdo con su esquema
create table big_table
(
updatetime datetime not null,
name char(14) not null,
TheData float,
primary key(Name,updatetime)
)
Luego llené la tabla con 50,000 filas con 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 SSMS, probé ambas consultas y me di cuenta de que en la primera consulta está buscando el MAX de TheData y en el segundo, el MAX del tiempo de actualización
Modifiqué así la primera consulta para obtener también el MAX del tiempo de actualización
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 Statistics Time obtengo la cantidad de milisegundos necesarios para analizar, compilar y ejecutar cada instrucción
Usando Statistics IO obtengo información sobre la actividad del disco
ESTADÍSTICAS TIEMPO y ESTADÍSTICAS IO proporcionan información útil. Tal como se usaron las tablas temporales (indicado por la tabla de trabajo). También cuántas páginas lógicas leídas se leyeron, lo que indica el número de páginas de la base de datos leídas de la memoria caché.
Luego activo el plan de ejecución con CTRL + M (activa mostrar el plan de ejecución real) y luego ejecuto con F5.
Esto proporcionará una comparación de ambas consultas.
Aquí está la salida de la pestaña Mensajes
- Consulta 1
Tabla 'tabla_grande'. Cuenta de escaneo 1, lecturas lógicas 543 , lecturas físicas 0, lecturas de lectura anticipada 0, lecturas lógicas lob 0, lecturas físicas lob 0, lecturas de lectura lob 0.
Tiempos de ejecución de SQL Server:
tiempo de CPU = 16 ms, tiempo transcurrido = 6 ms .
- Consulta 2
Mesa 'Mesa de trabajo '. Recuento de exploración 0, lecturas lógicas 0, lecturas físicas 0, lecturas de lectura anticipada 0, lecturas lógicas lob 0, lecturas físicas lob 0, lecturas de lectura lob 0.
Tabla 'tabla_grande'. Cuenta de escaneo 1, lecturas lógicas 543 , lecturas físicas 0, lecturas de lectura anticipada 0, lecturas lógicas lob 0, lecturas físicas lob 0, lecturas de lectura lob 0.
Tiempos de ejecución de SQL Server:
tiempo de CPU = 0 ms, tiempo transcurrido = 35 ms .
Ambas consultas dan como resultado 543 lecturas lógicas, pero la segunda consulta tiene un tiempo transcurrido de 35 ms, mientras que la primera tiene solo 6 ms. También notará que la segunda consulta da como resultado el uso de tablas temporales en tempdb, indicadas por la palabra tabla de trabajo . Aunque todos los valores de la tabla de trabajo están en 0, el trabajo todavía se realizó en tempdb.
Luego está la salida de la pestaña del plan de ejecución real al lado de la pestaña Mensajes
De acuerdo con el plan de ejecución proporcionado por MSSQL, la segunda consulta que proporcionó tiene un costo de lote total del 64%, mientras que la primera solo cuesta el 36% del lote total, por lo que la primera consulta requiere menos trabajo.
Con SSMS, puede probar y comparar sus consultas y descubrir exactamente cómo MSSQL analiza sus consultas y qué objetos: tablas, índices y / o estadísticas, si se están utilizando, para satisfacer esas consultas.
Una nota adicional adicional a tener en cuenta cuando se realizan pruebas es limpiar el caché antes de realizar las pruebas, si es posible. Esto ayuda a garantizar que las comparaciones sean precisas y esto es importante cuando se piensa en la actividad del disco. Comienzo con DBCC DROPCLEANBUFFERS y DBCC FREEPROCCACHE para limpiar todo el caché. Sin embargo, tenga cuidado de no utilizar estos comandos en un servidor de producción realmente en uso, ya que obligará efectivamente al servidor a leer todo desde el disco a la memoria.
Aquí está la documentación relevante.
- Borre el caché del plan con DBCC FREEPROCCACHE
- Elimine todo de la agrupación de almacenamientos intermedios con DBCC DROPCLEANBUFFERS
El uso de estos comandos puede no ser posible dependiendo de cómo se use su entorno.
Actualizado 28/10 12:46 pm
Se realizaron correcciones en la imagen del plan de ejecución y en la salida de estadísticas.
getdate()
salir del círculo