2011-11-29 32 views
7
SELECT X.ID, X.Field4 
FROM 
     #TaxInvoiceData T 
INNER JOIN 
     xxx X 
     ON T.Id = X.Id 
     AND Field2 = @VAR  
     AND Field3 = 'S' 

Khi tôi chạy một truy vấn một bảng đầy đủ quét trên bàn X. Tôi không hiểu tại sao vì Primary Key của Bảng X làTại sao bảng Scan được thực hiện?

ID INT ASC 
Field3 CHAR(2) ASC 
Field2 DATETIME ASC Unique Non-clustered 

Ngoài ra còn có một chỉ mục trên

Field2 DATETIME ASC Non-Unique Non-clustered 

Chỉ cần

SELECT ID 
FROM xxx 
WHERE 
    Field2 = @VAR 
AND Field3 = 'S' 

Chỉ mục tìm kiếm

Xin cảm ơn trước.

+0

Có bao nhiêu hàng trong #TaxInvoiceData? – Joe

+0

* Chỉ mục tìm kiếm * - ok, nhưng trên ** chỉ mục nào ** ??? Ngoài ra: bạn nói '(ID, Field2, Field3)' là khóa chính trên 'Bảng X' của bạn - đó là chỉ mục ** nhóm ** trên bảng? Hay đây là một đống ?? –

+0

S được tham gia như thế nào? Nó có thể là do khóa chính tôi không phân cụm nó nhanh hơn để quét bảng hơn là nhảy giữa chỉ mục và bảng cho mỗi hàng. – idstam

Trả lời

5

Câu trả lời ngắn: vì tôi ưu nghĩ rằng nó sẽ nhanh hơn.

Tuy nhiên, hãy thử đọc suy nghĩ của trình tối ưu hóa.

Vì bạn chưa cung cấp lược đồ bảng đầy đủ, tôi sẽ giả định rằng có một chỉ số nhóm trên xxx.ID và rằng #TaxInvoiceData là một đống. Bạn đang mong đợi một kế hoạch mà chỉ mục PK được thăm dò cho mỗi hàng trong #TaxInvoiceData, nhưng bạn đang chọn xxx.Field4 sẽ yêu cầu tra cứu dấu trang cho mỗi kết quả phù hợp. Điều này có thể dẫn đến 29.000 yêu cầu I/O ngẫu nhiên. Ouch.

Ngược lại, SQL Server có thể (và rõ ràng sẽ thực hiện) chỉ cần thực hiện một số lượng lớn hơn I/O tuần tự hiệu quả hơn khi quét bảng và có thể thực hiện một kết quả băm nhanh với #TaxInvoiceData.

Vì vậy, bạn có thể làm gì? Bạn có thể tạo chỉ mục bao gồm Field4. Hoặc bạn có thể sử dụng chỉ mục và tham gia gợi ý để buộc kế hoạch bạn đang tìm kiếm (nhưng tôi nghi ngờ hiệu suất sẽ không tốt như bạn mong đợi). Truy vấn này có được sử dụng thường xuyên đủ để cung cấp các vấn đề về hiệu suất ứng dụng của bạn hoặc bạn chỉ đang tìm cách loại bỏ quét bảng trên nguyên tắc? Nếu sau này, bạn có thể tìm thấy chi phí của việc loại bỏ việc quét không phải là giá trị nó cuối cùng.


Edit:

Vì bạn đã đề cập rằng không có nhóm chỉ số trên bảng, điều này cũng có thể ảnh hưởng đến cách hiệu quả tra cứu từ các chỉ số đang có. Trừ khi bảng này đang nhìn thấy hoạt động chèn cực kỳ nặng, hãy xem xét việc thay đổi PK của bạn thành nhóm. Điều đó một mình có thể thay đổi kế hoạch, và thậm chí nếu nó không có khả năng tăng tốc độ hoạt động khác do giảm chi phí.

+0

Cảm ơn bạn đã giải thích, mọi người đồng ý với điều đó. Nhưng tha thứ cho sự thiếu hiểu biết của tôi, tôi không hiểu tại sao Field4 tạo ra sự khác biệt vì nó là mệnh đề lựa chọn và không ở đâu tôi nghĩ nó sẽ hoạt động như thế này, tìm trang/hàng/lá theo mệnh đề where và lấy trường từ đó hàng. Vì vậy, tôi không hiểu làm thế nào một chỉ số của Field4 sẽ cải thiện một tìm kiếm. Ngoài ra không có chỉ số nhóm chỉ có PK được đặt thành Non-clustered vì bất kỳ lý do gì. – Mike

+5

Nếu mọi thứ mà nhu cầu truy vấn được chứa trong một chỉ mục, SQL Server chỉ có thể nhìn vào đó và tránh sử dụng toàn bộ bảng. Điều này được gọi là "chỉ mục bao trùm" cho truy vấn và thường rất hiệu quả. Đây không phải là trường hợp của bạn vì Field4 phải được đọc từ bảng. Vấn đề là do thực tế là nhiều lần (nhiều nghìn lần) nhìn lên hàng trong bảng được tham chiếu bởi một hàng chỉ mục không phải là rất hiệu quả do I/O overhead. Trình tối ưu hóa đang xem xét tất cả những điều này khi quyết định phải làm gì. – zinglon

-2

lẽ viết lại truy vấn sẽ giúp:

SELECT X.ID, X.Field4 
FROM xxx X, #TaxInvoiceData T 
WHERE X.Id = T.Id   
AND X.Field2 = @VAR    
AND X.Field3 = 'S' 
+0

Cảm ơn bạn đã dành thời gian, nhưng điều đó không thay đổi kế hoạch truy vấn. – Mike

+6

Đây không phải là cú pháp 'JOIN' chuẩn, viết lại truy vấn theo cách này sẽ không có tác động * và * làm cho mã tồi tệ hơn, -1 – Matthew

Các vấn đề liên quan