Mam zapytanie, które obecnie zajmuje średnio 2500 ms. Mój stół jest bardzo wąski, ale jest 44 miliony wierszy. Jakie opcje muszę poprawić, czy jest to tak dobre, jak to możliwe?
Zapytanie
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats]
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31';
Stół
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]
Indeks
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]
Czy dodanie dodatkowych indeksów pomogłoby? Jeśli tak, to jak by wyglądały? Obecna wydajność jest do zaakceptowania, ponieważ zapytanie jest uruchamiane tylko od czasu do czasu, ale zastanawiam się jako ćwiczenie edukacyjne, czy jest coś, co mogę zrobić, aby przyspieszyć?
AKTUALIZACJA
Gdy zmienię zapytanie, aby użyć podpowiedzi indeksu wymuszenia, zapytanie zostanie wykonane w ciągu 50 ms:
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats] WITH(INDEX(CommonQueryIndex))
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31'
Dodanie poprawnie selektywnej klauzuli DeviceID również uderza w zakres 50ms:
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats]
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31' AND DeviceID = 4;
Jeśli dodam ORDER BY [DateEntered], [DeviceID]
do pierwotnego zapytania, jestem w zakresie 50ms:
SELECT TOP 1000 * FROM [CIA_WIZ].[dbo].[Heartbeats]
WHERE [DateEntered] BETWEEN '2011-08-30' and '2011-08-31'
ORDER BY [DateEntered], [DeviceID];
Wszystkie używają indeksu, którego się spodziewałem (CommonQueryIndex), więc przypuszczam, że moje pytanie jest teraz, czy istnieje sposób na wymuszenie użycia tego indeksu w zapytaniach takich jak ten? A może rozmiar mojego stołu wyrzucający optymalizator jest zbyt duży i muszę po prostu skorzystać ORDER BY
z podpowiedzi?