รับตารางของรูปแบบทั่วไปดังต่อไปนี้:
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
);
ดัชนีต่อไปนี้มีประโยชน์:
CREATE INDEX f1
ON [Event] ([TimeStamp], EventTypeID)
INCLUDE (DeviceID)
WHERE EventTypeID IN (2, 5, 7, 8, 9, 14);
สำหรับแบบสอบถาม:
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);
ตัวกรองมีคุณสมบัติตรงตามข้อกำหนดของAND
คำสั่ง, คีย์แรกของดัชนีอนุญาตให้ค้นหาบน[TimeStamp]
ตัวกรองEventTypeIDs
และรวมถึงDeviceID
คอลัมน์ที่ทำให้ดัชนีครอบคลุม (เพราะDeviceID
จำเป็นสำหรับการเข้าร่วมในDevice
ตาราง)
คีย์ที่สองของดัชนี - EventTypeID
ไม่จำเป็นอย่างเคร่งครัด (อาจเป็นINCLUDEd
คอลัมน์) ผมได้รวมมันในกุญแจสำคัญสำหรับเหตุผลที่ระบุไว้ที่นี่ โดยทั่วไปฉันแนะนำให้คนรู้จักอย่างน้อยINCLUDE
คอลัมน์จากส่วนWHERE
คำสั่งดัชนีที่กรอง
จากแบบสอบถามและแผนการดำเนินการที่อัปเดตในคำถามฉันยอมรับว่าดัชนีทั่วไปที่แนะนำโดย SSMS น่าจะเป็นตัวเลือกที่ดีกว่าที่นี่เว้นแต่รายการของตัวกรองEventTypeIDs
จะคงที่ตามที่แอรอนกล่าวถึงในคำตอบของเขาด้วย:
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,
);
ดัชนีที่แนะนำ (ประกาศเป็นค่าเฉพาะหากเหมาะสม):
CREATE UNIQUE INDEX uq1
ON [Event]
(EventTypeID, PLCTimeStamp)
INCLUDE
(DeviceID, IATA, Data1, Data2, ID);
ข้อมูลความสำคัญจากแผนการดำเนินการ (ไวยากรณ์ที่ไม่มีเอกสารห้ามใช้ในระบบการผลิต):
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;
อัปเดตการสืบค้น (การทำซ้ำIN
รายการสำหรับEventType
ตารางช่วยให้เครื่องมือเพิ่มประสิทธิภาพในกรณีเฉพาะนี้):
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;
แผนการดำเนินการโดยประมาณ:
แผนที่คุณจะได้รับจะแตกต่างกันไปเนื่องจากฉันใช้สถิติที่เดาได้ จุดทั่วไปคือการให้เพิ่มประสิทธิภาพเป็นข้อมูลให้มากที่สุดเท่าที่จะทำได้และให้วิธีการเข้าถึงที่มีประสิทธิภาพ (ดัชนี) ใน 4 ล้านแถว[Event]
ของตาราง