Tại sao việc tạo chỉ mục mới này cải thiện hiệu suất rất nhiều khi chỉ mục hiện tại bao gồm tất cả các cột trong chỉ mục mới?


19

Tôi có bảng Log và LogItem; Tôi đang viết một truy vấn để lấy một số dữ liệu từ cả hai. Có hàng ngàn Logsvà mỗi Logcó thể có tới 125LogItems

Truy vấn trong câu hỏi rất phức tạp nên tôi bỏ qua nó (nếu ai đó nghĩ nó quan trọng tôi có thể đăng nó), nhưng khi tôi chạy gói Truy vấn Ước tính SSMS, nó đã cho tôi biết một chỉ mục Không phân cụm mới sẽ cải thiện hiệu suất lên tới 100% .

Existing Index: Non-clustered
Key Colums (LogItem): ParentLogID, DateModified, Name, DatabaseModified

Query Plan Recommendation
CREATE NONCLUSTERED INDEX [LogReportIndex]
ON [dbo].[LogItem] ([ParentLogID],[DatabaseModified])

Để giải trí, tôi đã tạo chỉ mục mới này và chạy truy vấn và thật ngạc nhiên, bây giờ mất ~ 1 giây để truy vấn của tôi chạy, khi trước đó là hơn 10 giây.

Tôi giả định rằng chỉ mục hiện tại của tôi sẽ bao gồm truy vấn mới này, vì vậy câu hỏi của tôi là tại sao việc tạo một chỉ mục mới trên các cột duy nhất được sử dụng trong truy vấn mới của tôi cải thiện hiệu suất? Tôi có nên có một chỉ mục cho mỗi tổ hợp cột duy nhất được sử dụng trong wheremệnh đề của mình không?

lưu ý: Tôi không nghĩ rằng điều này là do Máy chủ SQL đang lưu trữ kết quả của tôi, tôi đã chạy truy vấn khoảng 25-30 lần trước khi tôi tạo chỉ mục và nó mất liên tục 10 - 15 giây, sau khi chỉ mục hiện tại nhất quán ~ 1 hoặc ít hơn.


Trước khi bạn tạo chỉ mục không bao gồm bổ sung, kế hoạch thực hiện thực tế đã cho thấy việc sử dụng chỉ mục là gì?
Thomas Stringer

Hiệu suất được cải thiện 100% là gì?

@Shark Câu hỏi hay, tôi không chắc. Đây là tình huống gỡ lỗi hiệu suất đầu tiên của tôi. Tôi chắc chắn sẽ nắm lấy điều đó về phía trước. Tất cả những gì nó nói là 'Thiếu chỉ số' và nó nói trường nào.

@JeffO Đây là những gì SSMS đã nói: "Bộ xử lý truy vấn ước tính rằng việc thực hiện chỉ mục sau có thể cải thiện 100% chi phí truy vấn."

Câu trả lời:


21

Thứ tự các cột trong một chỉ mục là quan trọng. Nếu lọc yêu cầu cột 1 và 4 từ chỉ mục, chỉ mục sẽ không giúp ích. Nó chỉ hữu ích khi lọc theo N cột đầu tiên liên tiếp.

Điều này là do chỉ số là một cây. Bạn không thể chọn hiệu quả tất cả các nút của cây column3 = something, bởi vì chúng nằm rải rác ở mọi nơi khác, thuộc về các giá trị khác nhau của column1column2. Nhưng nếu bạn biết column1column2cũng như vậy, việc xác định đúng nhánh trong cây là không có trí tuệ.


Sau đó, có an toàn không khi giả định (nói chung) tôi cần một chỉ mục cho mỗi bộ mệnh đề "ở đâu" sẽ đánh vào bảng đó?

Tôi đã từng tăng tốc độ truy vấn của người khác chỉ bằng cách đảm bảo rằng nó sử dụng chỉ mục theo đúng thứ tự.

1
@Nate Rộng rãi, vâng. Một số wheres có thể trùng nhau, vì vậy bạn có thể có một chỉ mục bao gồm một vài wheres; hoặc bạn có thể bỏ qua một phần của wheremệnh đề vì lập chỉ mục trên một cột nhất định sẽ không giúp được gì (tính chọn lọc thấp); nhưng rộng rãi, vâng.

@Nate Bạn không muốn có nhiều chỉ mục hơn mức cần thiết. Mỗi chỉ mục mà SQL phải duy trì thêm chi phí riêng. Nếu bạn có thể sắp xếp lại các mệnh đề WHERE của mình để khớp với các cột N đầu tiên trên một chỉ mục hiện có, điều đó sẽ giúp bạn rất gần mà không cần thêm các chỉ mục bổ sung.
Đó là Chuck Guy

1
@ChuckBlumreich Thứ tự các cột trong wheremệnh đề không quan trọng. Máy chủ sẽ luôn sắp xếp chúng để sử dụng tốt nhất các chỉ số hiện có. Đó chỉ là một câu hỏi về việc có một chỉ mục bao gồm tất cả wherecác cột bắt buộc làm cột đầu tiên.

12

Các cạnh hàng đầu của một chỉ số là những gì quan trọng.

Miễn là truy vấn của bạn được "bao phủ" bởi cạnh hàng đầu của một chỉ mục, nó sẽ hiệu quả. Các chỉ mục cơ sở dữ liệu thường được triển khai dưới dạng B-Tree và cấu trúc của B-Tree cho rằng việc tìm kiếm phải được thực hiện theo một thứ tự nhất định, đó là lý do tại sao thứ tự các trường trong chỉ mục tổng hợp có vấn đề.

Nếu bạn có "lỗ hổng", ví dụ nếu bạn tìm kiếm trên ParentLogIDDatabaseModified, nhưng chỉ có chỉ mục trên {ParentLogID, DateModified, Name, DatabaseModified}thì chỉ {ParentLogID}có thể sử dụng một phần của chỉ mục một cách hiệu quả.

(LƯU Ý: Một số DBMS có thể sử dụng {DatabaseModified}phần thông qua "bỏ qua quét", nhưng ngay cả khi DBMS của bạn làm điều đó kém hiệu quả hơn nhiều so với truy cập chỉ mục thông thường) .


Vì vậy, nếu tôi có Columns (a, b, c, d, e, f)và hầu hết các truy vấn là ... WHERE A IN(...) AND B = 3chỉ mục của tôi Index(a,b,c,d)là một chỉ số tốt, nhưng nó không giúp ích gì nếu tôi có ... WHERE A IN (...) AND D = 5đó là lý do tại sao chỉ mục mới của tôi tôi thực hiện, Index(a,d)cải thiện hiệu suất rất nhiều, phải không?

8
@Nate - đúng. Hãy nghĩ về nó như một cuốn sách điện thoại. Nếu bạn chỉ biết tên của ai đó, bạn không thể tìm thấy mà không xem qua toàn bộ cuốn sách vì nó được tổ chức trên Lastname, Firstname
JNK
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.