Cho các bảng có dạng tổng quát sau:
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
);
Các chỉ số sau đây là hữu ích:
CREATE INDEX f1
ON [Event] ([TimeStamp], EventTypeID)
INCLUDE (DeviceID)
WHERE EventTypeID IN (2, 5, 7, 8, 9, 14);
Đối với truy vấn:
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);
Bộ lọc đáp ứng AND
yêu cầu mệnh đề, khóa đầu tiên của chỉ mục cho phép tìm kiếm đối [TimeStamp]
với bộ lọc EventTypeIDs
và bao gồm DeviceID
cột làm cho chỉ số bao phủ (vì DeviceID
được yêu cầu cho phép nối với Device
bảng).
Khóa thứ hai của chỉ mục - EventTypeID
không bắt buộc (nó cũng có thể là một INCLUDEd
cột); Tôi đã bao gồm nó trong khóa vì những lý do được nêu ở đây . Nói chung, tôi khuyên mọi người ít nhất là INCLUDE
các cột từ một WHERE
mệnh đề chỉ mục được lọc .
Dựa trên kế hoạch thực hiện và truy vấn được cập nhật trong câu hỏi, tôi đồng ý rằng chỉ số chung hơn được đề xuất bởi SSMS có thể là lựa chọn tốt hơn ở đây, trừ khi danh sách được lọc EventTypeIDs
là tĩnh vì Aaron cũng đề cập đến câu trả lời của mình:
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,
);
Chỉ mục được đề xuất (khai báo là duy nhất nếu phù hợp):
CREATE UNIQUE INDEX uq1
ON [Event]
(EventTypeID, PLCTimeStamp)
INCLUDE
(DeviceID, IATA, Data1, Data2, ID);
Thông tin về thẻ từ kế hoạch thực hiện (cú pháp không có giấy tờ, không sử dụng trong các hệ thống sản xuất):
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;
Truy vấn được cập nhật (lặp lại IN
danh sách cho EventType
bảng giúp trình tối ưu hóa trong trường hợp cụ thể này):
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;
Kế hoạch thực hiện dự kiến:
Kế hoạch bạn nhận được có thể sẽ khác bởi vì tôi đang sử dụng số liệu thống kê đoán. Điểm chung là cung cấp cho trình tối ưu hóa càng nhiều thông tin càng tốt và cung cấp phương thức truy cập (chỉ mục) hiệu quả trên [Event]
bảng hàng 4 triệu .