Quét bảng cụm vì vì LỰA CHỌN * CHỌN


7

Tôi có một Recordsbảng có hơn 100 cột và rất nhiều hàng và một chỉ mục không bao gồm trên 5 trường dựa trên các đường dẫn truy cập của tôi:

CREATE NONCLUSTERED INDEX [IX_Records_CustomerID]
ON [dbo].[Records] (
    [CustomerID] ASC, -- int
    [IsInvalid] ASC, -- int
    [IsProcessed] ASC, -- bit
    [IsRejected] ASC, -- bit
    [RecordName] ASC, -- varchar(12)
;

5 trường không bao gồm khóa chính RecordID, là cột trong chỉ mục được nhóm.

Đây là truy vấn hoạt động kém của tôi:

SELECT * FROM Records WHERE CustomerID IN (181, 283, 505)

Kế hoạch thực hiện cho thấy rằng nó thực hiện Quét chỉ mục cụm, điều tôi hiểu là vì tôi đang chọn các cột không được bao gồm trong chỉ mục. Trong Management Studio, tôi thay đổi truy vấn thành:

SELECT CustomerID, IsInvalid, IsProcessed, IsRejected, RecordName FROM Records 
    WHERE CustomerID IN (181, 283, 505)

Và kế hoạch thực hiện hiển thị Tìm kiếm chỉ mục và thời gian thực hiện truy vấn giảm từ 44 giây xuống còn 2 giây. Tuy nhiên, tôi thiếu sự tự do trong ứng dụng để thay thế *chỉ bằng các cột tôi cần và đã bao gồm trong chỉ mục của tôi.

Có cách nào xung quanh việc quét chỉ mục cụm khi tôi bị khóa SELECT *không?


Đó là thiết kế phụ. Việc quét bảng cho tất cả các trường rẻ hơn so với thực hiện 2 thao tác, một trên chỉ mục và một trên bảng.
Max Vernon

3
Nếu bạn quan tâm đến hiệu suất, bạn sẽ thay đổi ứng dụng. Ồ, và "người biểu diễn" có nghĩa là "người biểu diễn trong vở kịch, v.v.".
Max Vernon

1
Điều gì trong IN (…)truy vấn con?
Greenstone Walker

2
Như một giải pháp thay thế, bạn có thể tạo chế độ xem (chỉ với 5 cột bạn cần), sau đó cho phép ứng dụng sử dụng SELECT * FROM that_view WHERE CustomerID IN (...);không?
ypercubeᵀᴹ

1
@MaxVernon Cảm ơn bạn! "Người biểu diễn" bị ném xung quanh rất nhiều nơi tôi làm việc, bây giờ tôi biết! Tôi đã sửa đổi từ ngữ của tôi trong câu hỏi.
Chris Schiffhauer

Câu trả lời:


7

Nếu bạn cần các cột trong đầu ra không được chỉ số bao phủ, trình tối ưu hóa phải đưa ra lựa chọn:

  1. Thực hiện quét chỉ mục bảng / cụm (do đó tất cả các cột đều ở đó)
  2. Thực hiện tìm kiếm, sau đó thực hiện tra cứu để lấy các cột không được bảo hiểm

Cách nó sẽ chọn tùy thuộc vào nhiều thứ khác nhau, bao gồm chỉ số hẹp như thế nào, có bao nhiêu hàng khớp với vị ngữ, v.v. Bạn có thể buộc tìm kiếm với FORCESEEKgợi ý, nhưng tôi nghi ngờ nó sẽ kết thúc giống hoặc tệ hơn Máy chủ SQL quét đã chọn trong trường hợp của bạn.

Một số tùy chọn:

  1. Thay đổi ứng dụng để chạy một truy vấn thích hợp. Tôi liệt kê này đầu tiên vì một lý do .
  2. Tạo chế độ xem chỉ chọn các cột bạn cần:

    CREATE VIEW dbo.myview
    WITH SCHEMABINDING
    AS
      SELECT col1, col2, col3 FROM dbo.tablename;
    

    Sau đó, bạn có thể thay đổi ứng dụng SELECT *từ quan điểm này. Hoặc bạn có thể sáng tạo hơn nữa và đổi tên bảng gốc và thay đổi tên của dạng xem này thành tên của bảng được sử dụng. Thay đổi đột phá, rõ ràng; tiến hành thận trọng.

  3. Thêm tất cả các cột khác vào khóa hoặc INCLUDEdanh sách cho chỉ mục. Nếu đây là các giá trị được mã hóa cứng và luôn là giá trị được sử dụng, bạn có thể xem xét một chỉ mục được lọc.


2
Cảm ơn bạn và @MaxVernon vì đã nhấn mạnh tầm quan trọng của việc thay đổi truy vấn. Tôi sẽ mua lại từ các đồng nghiệp của mình và biến điều đó thành hiện thực.
Chris Schiffhauer

0

Có các trường khác trong chỉ mục sẽ làm cho nó tệ hơn nếu bạn luôn sử dụng select *. Hãy thử tạo chỉ mục cho ID khách hàng. Điều đó có thể giúp ích, nhưng nó phụ thuộc vào một số điều như có bao nhiêu ID trong danh sách và có bao nhiêu hàng trên mỗi ID khách hàng trong bả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.