Ho una query che attualmente richiede in media 2500 ms per il completamento. Il mio tavolo è molto stretto, ma ci sono 44 milioni di righe. Quali opzioni ho per migliorare le prestazioni o è buono come può?
The Query
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats]
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31';
La tavola
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]
L'indice
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]
L'aggiunta di ulteriori indici sarebbe di aiuto? In tal caso, come sarebbero? Le prestazioni attuali sono accettabili, poiché la query viene eseguita solo occasionalmente, ma mi chiedo come esercizio di apprendimento, c'è qualcosa che posso fare per renderlo più veloce?
AGGIORNARE
Quando cambio la query per utilizzare un suggerimento sull'indice di forza, la query viene eseguita in 50ms:
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats] WITH(INDEX(CommonQueryIndex))
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31'
L'aggiunta di una clausola DeviceID correttamente selettiva colpisce anche l'intervallo di 50ms:
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats]
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31' AND DeviceID = 4;
Se aggiungo ORDER BY [DateEntered], [DeviceID]
alla query originale, mi trovo nell'intervallo di 50 ms:
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats]
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31'
ORDER BY [DateEntered], [DeviceID];
Tutti usano l'indice che mi aspettavo (CommonQueryIndex), quindi, suppongo che la mia domanda sia ora, c'è un modo per forzare questo indice ad essere utilizzato su query come questa? O la dimensione del mio tavolo sta gettando troppo l'ottimizzatore e devo solo usare un ORDER BY
o un suggerimento?