Chỉ mục không phân cụm - khóa và phím không


8

Tôi chỉ muốn chắc chắn rằng tôi đang đi đúng hướng với các khái niệm này, vì vậy mọi phản hồi sẽ được đánh giá rất cao.

Đây là lý thuyết của tôi từ truy vấn tôi vừa tối ưu hóa, thông qua quá trình thử và sai và đọc tài liệu MSDN.

Truy vấn

DECLARE @pic_id int
SET pic_id = 1

SELECT ROW_NUMBER() OVER (ORDER BY pic_date desc) AS row_num, *
FROM tbl_pics
WHERE deleted = 0 AND map_id = 1 AND (hidden = 0 OR pic_id = @pic_id)

Chỉ số

CREATE NONCLUSTERED INDEX [IX_tbl_pics] ON [dbo].[tbl_pics] 
(
    [map_id] ASC,
    [deleted] ASC,
    [pic_date] DESC
)
INCLUDE ( [hidden], [pic_id] )

Ngoài ra còn có một chỉ số PK trên pic_id

Học thuyết

Các cột chính là như vậy, bởi vì chúng được sử dụng trong mệnh đề WHERE (nhưng không được sử dụng trong tình huống OR) hoặc ORDER BY.

Các cột không khóa (INCLUDE) là như vậy, vì chúng được sử dụng trong WHERE, nhưng vì chúng được sử dụng trong kịch bản OR nên chúng không thể (không thể cải thiện hiệu suất) là một cột chính.

Những giả định này có đúng không? Nếu không, tôi còn thiếu gì?

Cảm ơn!

Câu trả lời:


8

Bạn đang yêu cầu trình tối ưu hóa truy vấn để tạo một kế hoạch có thể trả lời truy vấn:

SELECT *
FROM tbl_pics
WHERE deleted = 0 AND map_id = 1 AND hidden = 0;

Phần còn lại là lông tơ (bao gồm cả OR pic_id = @pic_id). Đây sẽ là một lần quét bảng, được đảm bảo, vì tính chọn lọc thấp của các vị từ liên quan (Tôi chắc chắn deletedhiddenlà 0/1, và map_iptôi nghi ngờ nó có bất kỳ tác động đáng kể nào). Vị từ duy nhất có thể lưu truy vấn là pic_id = @pic_idnhưng bằng cách đặt nó trong điều kiện HOẶC bạn đã giết chết cơ hội. Không có chỉ số phụ có thể giúp nó, thực tế. Việc bổ sung ROW_NUMBER sẽ quảng cáo một loại, rất có thể, nhưng thiệt hại thực sự là quét.

Đây là một nguyên nhân bị mất. Hãy đến với các yêu cầu thực tế.


6

Là khóa chính cũng là chỉ số cụm? Nếu vậy, không có lý do gì INCLUDE (pic_id)vì chỉ mục cụm duy nhất sẽ được sử dụng làm dấu trang trong chỉ mục không bao gồm.

Theo như những gì bạn đang nói với OR, đó thực sự là một phần thứ hai của WHERE, nhưng bạn chỉ dựa vào sự chọn lọc của người đầu tiên để thực hiện hầu hết công việc (trong khi dựa vào INCLUDE để tránh đi đến cái bàn).

Nhưng bằng cách có * trong đó, bạn có thể phải đi đến bàn nào.

Mặt khác, tôi có thể không thiết kế các chỉ mục của mình dựa trên một truy vấn duy nhất trừ khi truy vấn này được sử dụng rất nhiều mà không tính đến tải nhiều hơn. Và vẫn có một cái nhìn vào kế hoạch thực hiện không thể làm tổn thương.

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.