Thiếu chỉ mục không cụm đã là một phần của chỉ mục cụm


9

Tôi đang gỡ lỗi một truy vấn chạy chậm và trong kế hoạch thực hiện, một chỉ mục không được phân cụm được đề xuất, với 51.6648 Impact. Tuy nhiên, chỉ mục không được phân cụm chỉ bao gồm các cột đã có trong Chỉ mục cụm tổng hợp khóa chính (PK).

Điều này có thể là do thứ tự của các cột trong chỉ mục? tức là nếu các cột trong chỉ mục được nhóm không theo thứ tự từ hầu hết được chọn đến ít nhất thì có khả năng cho một chỉ mục không được phân cụm để cải thiện hiệu suất không?

Ngoài ra, chỉ mục không phân cụm chỉ chứa hai trong số ba cột PK với cột thứ ba được thêm dưới dạng cột được bao gồm. Là includemột lý do khác tại sao việc sử dụng chỉ mục không phân cụm có thể tối ưu hơn?

Dưới đây là một ví dụ về cấu trúc bảng tôi đang làm việc với:

Những cái bàn-

Retailers (
    RetailerID int PK, 
    name ...)

Retailer_Relation_Types (
    RelationType smallint PK, 
    Description nvarchar(50) ...)

Retailer_Relations (
    RetailerID int PK FK, 
    RelatedRetailerID int PK FK, 
    RelationType smallint PK FK, 
    CreatedOn datetime ...)

Bảng Retailer_Relationscó chỉ số PK tổng hợp sau và chỉ mục được đề xuất-

CONSTRAINT PK_Retailer_Relations 
PRIMARY KEY CLUSTERED (
    RetailerID ASC, 
    RelatedRetailerID ASC, 
    RelationType ASC
    ) ON [PRIMARY]

CREATE NONCLUSTERED INDEX <NameOfIndex> 
ON Retailer_Relations (
    RetailerID, 
    RelationType
    ) 
INCLUDE (
    RelatedRetailerID
    )

Câu trả lời:


12

Bảng Retailer_Relations có chỉ mục PK tổng hợp và chỉ mục được đề xuất-

Mặc dù các chỉ mục bị thiếu có thể hữu ích và chắc chắn có thể hoạt động, tôi sẽ không dành quá nhiều thời gian cho các chỉ mục bị thiếu, những gợi ý này được tạo ra trong kế hoạch thực hiện ước tính, không phải trên kế hoạch thực hiện thực tế.

Chính xác hơn, các gợi ý chỉ mục này dựa trên tiền đề giảm chi phí Truy vấn Bucks ™ được sử dụng bởi các nhà khai thác trong kế hoạch. Trình tối ưu hóa tính toán các chi phí ước tính và thêm các gợi ý chỉ số bị thiếu tương ứng.

Kết quả là họ có thể rất sai. Nếu bạn không chắc chắn liệu nó có giúp ích hay không, điều tốt nhất nên làm là kiểm tra tình huống trước và sau. Bạn có thể làm điều này bằng cách thêm câu lệnh SET STATISTICS IO, TIME ON;trước khi chạy truy vấn.

Ngoài ra, bạn có thể sử dụng công cụ thống kê để đọc các số liệu thống kê này dễ dàng hơn.

Điều này có thể là do thứ tự của các cột trong chỉ mục?

Điều đó là chính xác, việc tạo chỉ mục bị thiếu có thể cải thiện tính chọn lọc trên các truy vấn, ví dụ: nếu truy vấn của bạn trông như thế này:

SELECT  RelatedRetailerID
FROM Retailer_Relations 
WHERE
RetailerID = 5 AND
RelationType = 20;

hoặc như thế này:

SELECT  RelatedRetailerID
FROM Retailer_Relations 
ORDER BY
RetailerID,
RelationType;

Lý do đằng sau điều này là cả hai chỉ mục có thể tìm kiếm trên RetailerID, phần đó sẽ không thay đổi. Nhưng nếu bộ lọc / thứ tự bổ sung được áp dụng trên RelationType thì sao? Nó sẽ ở khắp mọi nơi trong chỉ mục được nhóm, do kết quả của nó là giá trị khóa thứ ba, không phải giá trị khóa thứ hai. Và như chúng ta biết, nó là giá trị quan trọng thứ hai trong NCI.

Được rồi, nhưng khi nào hoặc làm thế nào chỉ mục không bao gồm sẽ cải thiện truy vấn?

Một vài trường hợp có thể là:

  • Nếu mối quan hệ lọc nhiều giá trị, I / O dư có thể cao, dẫn đến nhu cầu có thể của chỉ mục không được bao gồm (Truy vấn # 1)
  • Việc đặt hàng trên hai cột xảy ra (Một chiều) và tập kết quả lớn (Truy vấn # 2).
  • Như @AaronBertrand đã đề cập: nếu chênh lệch kích thước CI so với NCI là một số lượng đáng kể, việc thêm NCI sẽ làm giảm các trang được đọc bởi các truy vấn có lợi từ nó.

Ghi chú bên NCI

Là một lưu ý phụ, việc thêm các cột chính vào danh sách bao gồm trong NCI của bạn là không thực sự cần thiết, vì các cột khóa CI được tự động đưa vào tất cả các chỉ mục Không được nhóm.

Bạn có thể chọn làm như vậy nếu bạn không chắc chắn liệu chỉ mục được nhóm có giữ nguyên không và muốn cột luôn được đưa vào.

Về chính truy vấn, nếu bạn đã thêm kế hoạch thực hiện thông qua PasteThePlan, chúng tôi có thể cung cấp thêm một số thông tin về lập chỉ mục / cải thiện truy vấn.


Kiểm tra

Tạo bảng và thêm một số hàng

CREATE TABLE Retailer_Relations (
    RetailerID int , 
    RelatedRetailerID int , 
    RelationType smallint, 
    CreatedOn datetime,
    CONSTRAINT PK_Retailer_Relations 
PRIMARY KEY CLUSTERED (
    RetailerID ASC, 
    RelatedRetailerID ASC, 
    RelationType ASC
    ) ON [PRIMARY])


    DECLARE @I Int = 1
    WHILE @I < 1000
    BEGIN
    INSERT INTO Retailer_Relations(RetailerID,RelatedRetailerID,RelationType,CreatedOn)
    VALUES(@I,@I,@I,GETDATE()
    )
    set @I += 1
    END

Truy vấn số 1

    SELECT  RelatedRetailerID
FROM Retailer_Relations 
WHERE
RetailerID = 5 AND
RelationType = 20;

Kế hoạch không có chỉ số ở đây

Trong khi nó đang thực hiện tìm kiếm, nó đang thực hiện tìm kiếm trên RetailerID. Sau đó, nó đang phát hành một biến vị ngữ I / O dư trên RelationType

Thêm chỉ mục

CREATE NONCLUSTERED INDEX IX_TEST
ON Retailer_Relations (
    RetailerID, 
    RelationType
    ) 
INCLUDE (
    RelatedRetailerID
    )

Vị từ còn lại đã biến mất, mọi thứ xảy ra trong một vị từ tìm kiếm, trên cả hai cột.

Kế hoạch thực hiện

Với truy vấn thứ hai, tính hữu ích của chỉ mục được thêm vào càng trở nên rõ ràng hơn:

SELECT  RelatedRetailerID
FROM Retailer_Relations 
ORDER BY
RetailerID,
RelationType;

Lập kế hoạch mà không có chỉ mục, với toán tử Sắp xếp:

nhập mô tả hình ảnh ở đây

Lập kế hoạch với chỉ mục, sử dụng chỉ mục sẽ loại bỏ toán tử sắp xếp

nhập mô tả hình ảnh ở đây


1
Cảm ơn Randi, tôi sẽ đánh dấu đây là câu trả lời nhưng chỉ muốn hỏi là bạn có nói gợi ý Chỉ số bị thiếu dựa trên Kế hoạch thực hiện ước tính không? Tôi hỏi điều này vì nó được hiển thị trong Kế hoạch thực hiện thực tế trong SS2016.
Fletch

1
Tôi tự hỏi nếu đó là những gì bạn đang nói, cảm ơn vì đã làm rõ.
Fletch
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.