J'ai une requête qui prend actuellement en moyenne 2500 ms pour être terminée. Ma table est très étroite, mais il y a 44 millions de lignes. Quelles options dois-je pour améliorer les performances, ou est-ce aussi bon que possible?
La requête
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats]
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31';
La table
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'index
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'ajout d'index supplémentaires aiderait-il? Si oui, à quoi ressembleraient-ils? Les performances actuelles sont acceptables, car la requête n'est exécutée qu'occasionnellement, mais je me demande, en tant qu'exercice d'apprentissage, que puis-je faire pour accélérer le processus?
MISE À JOUR
Lorsque je modifie la requête pour utiliser un indice d'index de force, la requête s'exécute en 50 ms:
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats] WITH(INDEX(CommonQueryIndex))
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31'
L'ajout d'une clause DeviceID correctement sélective atteint également la plage 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 j'ajoute ORDER BY [DateEntered], [DeviceID]
à la requête d'origine, je suis dans la plage des 50 ms:
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats]
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31'
ORDER BY [DateEntered], [DeviceID];
Tout cela utilise l'index que j'attendais (CommonQueryIndex) donc, je suppose que ma question est maintenant, existe-t-il un moyen de forcer cet index à être utilisé sur des requêtes comme celle-ci? Ou la taille de ma table rejette-t-elle trop l'optimiseur et je dois simplement utiliser un ORDER BY
ou un indice?