Tengo una consulta que actualmente tarda un promedio de 2500 ms en completarse. Mi mesa es muy estrecha, pero hay 44 millones de filas. ¿Qué opciones tengo para mejorar el rendimiento, o es tan bueno como es posible?
La consulta
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats]
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31';
La mesa
CREATE TABLE [dbo].[Heartbeats](
[ID] [int] IDENTITY(1,1) NOT NULL,
[DeviceID] [int] NOT NULL,
[IsPUp] [bit] NOT NULL,
[IsWebUp] [bit] NOT NULL,
[IsPingUp] [bit] NOT NULL,
[DateEntered] [datetime] NOT NULL,
CONSTRAINT [PK_Heartbeats] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
El índice
CREATE NONCLUSTERED INDEX [CommonQueryIndex] ON [dbo].[Heartbeats]
(
[DateEntered] ASC,
[DeviceID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
¿Sería útil agregar índices adicionales? Si es así, ¿cómo se verían? El rendimiento actual es aceptable, porque la consulta solo se ejecuta ocasionalmente, pero me pregunto como ejercicio de aprendizaje, ¿hay algo que pueda hacer para que esto sea más rápido?
ACTUALIZAR
Cuando cambio la consulta para usar una pista de índice de fuerza, la consulta se ejecuta en 50 ms:
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats] WITH(INDEX(CommonQueryIndex))
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31'
Agregar una cláusula DeviceID correctamente selectiva también alcanza el rango de 50 ms:
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats]
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31' AND DeviceID = 4;
Si agrego ORDER BY [DateEntered], [DeviceID]
a la consulta original, estoy en el rango de 50 ms:
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats]
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31'
ORDER BY [DateEntered], [DeviceID];
Todos usan el índice que esperaba (CommonQueryIndex), así que supongo que mi pregunta es ahora, ¿hay alguna manera de forzar este índice para que se use en consultas como esta? ¿O es que el tamaño de mi mesa arroja demasiado el optimizador y debo usar una ORDER BY
o una pista?