2009-08-31 27 views
7

Tôi đã có một thủ tục lưu trữ trong SQL Server 2005 và khi tôi chạy nó và tôi nhìn vào kế hoạch thực hiện của nó, tôi nhận thấy nó đang làm một Clustered Index Scan, và điều này khiến nó mất 84%. Tôi đã đọc rằng tôi đã phải sửa đổi một số thứ để có được một chỉ mục Clustered Seek ở đó, nhưng tôi không biết phải sửa đổi gì.Tôi nên làm gì để có được chỉ mục Clustered Index Search thay vì Clustered Index Scan?

Tôi sẽ đánh giá cao bất kỳ trợ giúp nào về vấn đề này.

Cảm ơn,

Brian

+1

Truy vấn và giản đồ bảng như thế nào? –

Trả lời

19

W/o bất kỳ chi tiết nào cũng khó đoán được vấn đề là gì và ngay cả khi có vấn đề gì. Lựa chọn quét thay vì tìm kiếm có thể được thúc đẩy bởi nhiều yếu tố:

  • Truy vấn thể hiện tập kết quả bao trùm toàn bộ bảng. I E. truy vấn là một đơn giản SELECT * FROM <table>. Đây là một trường hợp tầm thường mà sẽ được bao phủ hoàn toàn bởi một quét chỉ mục clustred mà không cần phải xem xét bất cứ điều gì khác.
  • Các ưu không có lựa chọn thay thế:
    • truy vấn thể hiện một tập hợp con của toàn bộ bảng, nhưng vị lọc là trên các cột mà không phải là một phần của chính nhóm và không có chỉ số phi clustred trên các cột hoặc. Đây không phải là kế hoạch thay thế ngoài một lần quét toàn bộ.
    • Truy vấn có lọc các vị từ trên các cột trong khóa chỉ mục được đánh cắp, nhưng chúng không phải là SARGable. Các vị từ lọc thường cần phải được viết lại để làm cho nó SARGable, viết lại thích hợp phụ thuộc từng trường hợp. Một vấn đề tinh tế hơn có thể xuất hiện do các quy tắc chuyển đổi tiềm ẩn, ví dụ: vị từ lọc là WHERE column = @value nhưng cột là VARCHAR (Ascii) và @value là NVARCHAR (Unicode).
    • Truy vấn có các vị từ lọc SARGale trên các cột trong khóa được nhóm, nhưng cột ngoài cùng bên trái không được lọc. I E. chỉ số clustred là trên các cột (foo, bar) nhưng mệnh đề WHERE chỉ ở trên bar một mình.
  • Trình tối ưu hóa chọn quét.
    • Khi thay thế là một chỉ số không clustered sau đó quét (hoặc phạm vi tìm kiếm) nhưng sự lựa chọn là một sử dụng các chỉ số nhóm nguyên nhân có thể thường theo dõi xuống index tipping point do thiếu non-clustered độ bao phủ chỉ mục cho phép chiếu truy vấn. Lưu ý rằng đây không phải là câu hỏi của bạn, vì bạn mong đợi một chỉ số nhóm tìm kiếm, không phải là một chỉ mục không liên kết (giả sử câu hỏi là chính xác 100% và được ghi lại ...)
    • Ước tính thẻ. Ước tính chi phí truy vấn được dựa trên số liệu thống kê (các) số liệu chỉ mục nhóm, cung cấp ước tính về số lượng của kết quả (tức là có bao nhiêu hàng sẽ khớp). Trên truy vấn đơn giản Điều này không thể xảy ra, vì bất kỳ ước tính nào cho tìm kiếm hoặc phạm vi tìm kiếm sẽ thấp hơn giá trị tìm kiếm, bất kể số liệu thống kê như thế nào, nhưng trên truy vấn phức tạp, cùng với các bộ lọc và kết nối trên nhiều bảng , mọi thứ phức tạp hơn và kế hoạch có thể bao gồm quét nơi tìm kiếm được mong đợi vì trình tối ưu hóa truy vấn có thể chọn gói mà thứ tự đánh giá tham gia được đảo ngược với những gì người quan sát mong đợi. Sự lựa chọn thứ tự ngược lại có thể chính xác (hầu hết các lần) hoặc có thể có vấn đề (thường là do các số liệu thống kê bị lỗi thời hoặc tham số sniffing).
    • Đảm bảo đặt hàng. Việc quét sẽ tạo ra kết quả theo thứ tự được đảm bảo và các phần tử cao hơn trên cây thực thi có thể được hưởng lợi từ thứ tự này (ví dụ: một loại hoặc ống có thể bị loại bỏ, hoặc một phép nối hợp nhất có thể được sử dụng thay vì kết nối băm/lồng nhau). Nhìn chung, chi phí truy vấn tốt hơn do việc chọn đường dẫn truy cập chậm hơn.

Đây là một số gợi ý nhanh chóng tại sao một nhóm chỉ số quét có thể có mặt khi một nhóm chỉ số tìm kiếm được mong đợi. Câu hỏi là cực kỳ chung chung và không thể đưa ra một câu trả lời 'tại sao', khác hơn là dựa vào một quả bóng 8. Bây giờ nếu tôi đưa câu hỏi của bạn vào đúng tài liệu và được khớp chính xác, thì hãy mong đợi một chỉ mục nhóm tìm kiếm điều đó có nghĩa là bạn đang tìm kiếm một bản ghi duy nhất dựa trên giá trị khóa chính. Trong trường hợp này, vấn đề phải có với SARGability của mệnh đề WHERE.

+0

"Trên truy vấn đơn giản Điều này không thể xảy ra, vì bất kỳ ước tính nào cho tìm kiếm hoặc phạm vi tìm kiếm sẽ thấp hơn giá trị tìm kiếm" ... không đúng ... Nếu chỉ có 10% hàng có 'Đặc biệt = đúng (1) ', sau đó truy vấn đơn giản' Chọn * Từ bảng trong đó Đặc biệt = 0' Sẽ luôn chọn một bảng Quét. Đây là trường hợp ngay cả khi chỉ mục tồn tại trên cột Đặc biệt, miễn là chỉ mục không phải là chỉ mục nhóm. (Nếu chỉ mục là chỉ số nhóm, thì trình tối ưu hóa dĩ nhiên sẽ chọn một phạm vi tìm kiếm.) –

+0

@Charles: nhưng đó là 'điểm chỉ số' tại nơi làm việc, mà tôi vừa đề cập. Btw, truy vấn ví dụ của bạn không phải là 'đơn giản' (ví dụ: tầm thường, xem http://msdn.microsoft.com/en-us/library/aa226174%28SQL.70%29.aspx): "câu lệnh SELECT trong đó tất cả các cột nằm trong chỉ mục bao gồm duy nhất và không có chỉ mục nào khác có tập hợp các cột trong đó. " –

+0

nếu đó là những gì bạn có nghĩa là "Đơn giản" thì tôi có thể đồng ý về mặt kỹ thuật, nhưng trong bối cảnh, nếu làm rõ ý nghĩa của từ 'đơn giản', người đọc sẽ có một ấn tượng rất khác, không chính xác. Nếu bạn đặt từ 'đơn giản' trong dấu ngoặc kép hoặc được đánh dấu, với định nghĩa y trong ngoặc hoặc như chú thích, thì tốt ... Nếu không trình đọc giả định rằng bất kỳ truy vấn 'đơn giản' nào sẽ không có vấn đề này, và điều đó không chính xác, những lý do bạn đề cập đến. ... để làm trầm trọng thêm vấn đề, sau đó bạn bán xác định phức tạp như liên quan đến sự phức tạp tham gia, mà không liên quan đến vấn đề lật. –

5

Nếu Query incldues hơn một tỷ lệ nhất định của các hàng trong bảng, tôi ưu hoa sẽ bầu ra để làm một quét thay vì một tìm kiếm, vì nó dự đoán rằng nó sẽ yêu cầu đĩa IO ít hơn trong trường hợp đó (Đối với một Seek, Nó cần một IO đĩa cho mỗi cấp trong chỉ mục cho mỗi hàng nó trả về), trong khi quét chỉ có một đĩa IO mỗi hàng trong toàn bộ bảng. Vì vậy, nếu có, nói 5 cấp độ trong chỉ mục b-tree, sau đó nếu truy vấn sẽ tạo ra hơn 20% số hàng trong bảng, nó là rẻ hơn để đọc toàn bộ bảng hơn làm cho 5 IOs cho mỗi của 20% hàng ...

Bạn có thể thu hẹp đầu ra của truy vấn nhiều hơn một chút để giảm số lượng hàng được trả về bởi bước này trong quá trình không? Điều đó sẽ giúp nó chọn tìm kiếm trong quá trình quét.

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