Diberikan tabel bentuk umum berikut:
CREATE TABLE Device
(
ID integer PRIMARY KEY
);
CREATE TABLE EventType
(
ID integer PRIMARY KEY,
Name nvarchar(50) NOT NULL
);
CREATE TABLE [Event]
(
ID integer PRIMARY KEY,
[TimeStamp] datetime NOT NULL,
EventTypeID integer NOT NULL REFERENCES EventType,
DeviceID integer NOT NULL REFERENCES Device
);
Indeks berikut bermanfaat:
CREATE INDEX f1
ON [Event] ([TimeStamp], EventTypeID)
INCLUDE (DeviceID)
WHERE EventTypeID IN (2, 5, 7, 8, 9, 14);
Untuk kueri:
SELECT
[Event].ID,
[Event].[TimeStamp],
EventType.Name,
Device.ID
FROM
[Event]
INNER JOIN EventType ON EventType.ID = [Event].EventTypeID
INNER JOIN Device ON Device.ID = [Event].DeviceID
WHERE
[Event].[TimeStamp] BETWEEN '2011-01-28' AND '2011-01-29'
AND Event.EventTypeID IN (2, 5, 7, 8, 9, 14);
Filter memenuhi ANDpersyaratan klausa, kunci pertama indeks memungkinkan pencarian [TimeStamp]untuk difilter EventTypeIDsdan termasuk DeviceIDkolom membuat indeks meliputi (karena DeviceIDdiperlukan untuk bergabung ke Devicetabel).

Kunci kedua dari indeks - EventTypeIDtidak sepenuhnya diperlukan (bisa juga berupa INCLUDEdkolom); Saya telah memasukkannya ke dalam kunci karena alasan yang disebutkan di sini . Secara umum, saya menyarankan orang untuk setidaknya INCLUDEkolom dari WHEREklausa indeks yang difilter .
Berdasarkan permintaan yang diperbarui dan rencana eksekusi dalam pertanyaan, saya setuju bahwa indeks yang lebih umum yang disarankan oleh SSMS kemungkinan adalah pilihan yang lebih baik di sini, kecuali daftar yang difilter EventTypeIDsbersifat statis karena Aaron juga menyebutkan dalam jawabannya:
CREATE TABLE Device
(
ID integer PRIMARY KEY,
Name nvarchar(50) NOT NULL UNIQUE
);
CREATE TABLE EventType
(
ID integer PRIMARY KEY,
Name nvarchar(20) NOT NULL UNIQUE,
[Description] nvarchar(100) NOT NULL
);
CREATE TABLE [Event]
(
ID integer PRIMARY KEY,
PLCTimeStamp datetime NOT NULL,
EventTypeID integer NOT NULL REFERENCES EventType,
DeviceID integer NOT NULL REFERENCES Device,
IATA varchar(50) NOT NULL,
Data1 integer NULL,
Data2 integer NULL,
);
Indeks yang disarankan (nyatakan unik jika sesuai):
CREATE UNIQUE INDEX uq1
ON [Event]
(EventTypeID, PLCTimeStamp)
INCLUDE
(DeviceID, IATA, Data1, Data2, ID);
Informasi kardinalitas dari rencana eksekusi (sintaksis tidak berdokumen, jangan gunakan dalam sistem produksi):
UPDATE STATISTICS dbo.Event WITH ROWCOUNT = 4042700, PAGECOUNT = 400000;
UPDATE STATISTICS dbo.EventType WITH ROWCOUNT = 22, PAGECOUNT = 1;
UPDATE STATISTICS dbo.Device WITH ROWCOUNT = 2806, PAGECOUNT = 28;
Kueri yang diperbarui (mengulangi INdaftar untuk EventTypetabel membantu pengoptimal dalam kasus khusus ini):
SELECT
Event.ID,
Event.IATA,
Device.Name,
EventType.Description,
Event.Data1,
Event.Data2,
Event.PLCTimeStamp,
Event.EventTypeID
FROM
Event
INNER JOIN EventType ON EventType.ID = Event.EventTypeID
INNER JOIN Device ON Device.ID = Event.DeviceID
WHERE
Event.EventTypeID IN (3, 30, 40, 41, 42, 46, 49, 50)
AND EventType.ID IN (3, 30, 40, 41, 42, 46, 49, 50)
AND Event.PLCTimeStamp BETWEEN '2011-01-28' AND '2011-01-29'
AND Event.IATA LIKE '%0005836217%'
ORDER BY Event.ID;
Perkiraan rencana eksekusi:

Paket yang Anda dapatkan kemungkinan akan berbeda karena saya menggunakan statistik dugaan. Poin umumnya adalah memberikan pengoptimal sebanyak mungkin informasi, dan memberikan metode akses (indeks) yang efisien pada [Event]tabel 4-juta baris .