2010-01-21 36 views
6

Tôi đã thực hiện một truy vấn và bao gồm Kế hoạch Thực thi Thực tế. Có một Hash Match mà tôi quan tâm vì nó là subtree sử dụng một chỉ mục Scan thay vì chỉ mục tìm kiếm. Khi tôi di chuột qua Hash Match này, có một phần được gọi là "Probe Dư". Tôi đã giả định rằng đây là bất kỳ giá trị nào tôi tham gia. Tôi có chính xác ở đây hay là có một lời giải thích tốt hơn về điều đó có nghĩa là gì?Câu hỏi về cách đọc kế hoạch Thực thi SQL

Câu hỏi thứ hai tôi có là về các chỉ mục mà nó sử dụng. Trong ví dụ của tôi, tôi khá chắc chắn sự tham gia đặc biệt này đang tham gia vào hai cột. Chỉ mục mà nó đang quét có cả hai cột này trong cột cũng như cột khác không được sử dụng trong kết nối. Tôi đã ấn tượng rằng điều này sẽ dẫn đến một Index Index thay vì một Scan. Tôi có nhầm lẫn về điều này không?

Trả lời

4

Tham số băm sẽ thường (luôn luôn?) Sử dụng quét hoặc ít nhất là quét phạm vi. Một phép nối băm hoạt động bằng cách quét cả hai bảng nối trái và phải (hoặc một phạm vi trong các bảng) và xây dựng một bảng băm trong bộ nhớ chứa tất cả các giá trị được nhìn thấy bởi các lần quét.

Điều xảy ra trong trường hợp của bạn là: QO nhận thấy rằng nó có thể lấy tất cả các giá trị của cột C từ chỉ mục không nhóm có chứa cột này (dưới dạng khóa hoặc cột được bao gồm). Là một chỉ số không nhóm có lẽ là khá hẹp, do đó tổng số tiền của IO để quét toàn bộ chỉ mục không được nhóm không phải là quá mức. QO cũng cho rằng hệ thống có đủ RAM để lưu trữ một bảng băm trong bộ nhớ. Khi so sánh chi phí của truy vấn này (quét một chỉ mục không được nhóm lại từ đầu đến cuối, ví dụ, 10000 trang) với chi phí của vòng lặp lồng nhau sử dụng tìm kiếm (nói 5000 đầu dò ở 2-3 trang) quét thắng như yêu cầu ít IO. Tất nhiên, phần lớn là suy đoán về phía tôi, nhưng tôi đang cố gắng trình bày trường hợp từ quan điểm QO, và kế hoạch có thể là tối ưu.

yếu tố góp phần vào sự lựa chọn phương án đặc biệt này sẽ là:

  • một số lượng lớn các ứng cử viên dự kiến ​​ở phía bên phải của kết nối
  • sẵn có của gia cột trong một index hẹp non-clustered cho phía bên trái
  • nhiều RAM

Đối với một ước tính lớn số lượng ứng cử viên, một sự lựa chọn tốt hơn so với băm tham gia chỉ là merge-tham gia, và rằng một yêu cầu đầu vào phải được phân loại. Nếu cả hai phía bên trái có thể cung cấp một đường dẫn truy cập đảm bảo một đơn đặt hàng trên cột được nối và phía bên phải có khả năng tương tự thì bạn có thể kết thúc với phép nối hợp nhất, đó là phép nối nhanh nhất.

+3

Kết hợp băm không nhất thiết phải sử dụng Quét. Nó có thể dễ dàng liên quan đến Tìm kiếm đến các bản ghi cụ thể và sau đó sử dụng các kết quả của Tìm kiếm đó trong Kết hợp băm. Đối với một Nested Loop, nó xử lý một bản ghi tại một thời điểm, do đó, có nhiều khả năng thích một Seek, nhưng điều đó không có nghĩa là một Hash sẽ thích quét - nó chỉ cần để có được tất cả các hàng có tiềm năng phù hợp. Nếu bạn lọc trên cả hai bảng có liên quan và có chỉ mục bao gồm nhưng cũng là phép tính, bạn có thể tạo lại hành vi này. –

+0

@Rob: Tôi không được bán trên đó. Đã cho tôi một thời gian để tìm một công khai có sẵn ref trên nó, nhưng đọc http://blogs.msdn.com/craigfr/archive/2006/08/10/687630.aspx về cách Hash-Join hoạt động, cả việc xây dựng và thăm dò giai đoạn * đọc toàn bộ đầu vào trong một lần * loại quy tắc nào tìm kiếm. Ngoài ra thuật toán giả nêu rõ rằng không có mối tương quan giữa bên trái và bên phải xác định lọc thăm dò. –

+0

Phải ... chúng ta hãy xem xét thiết lập đầu tiên. Tạo hai bảng, với hai trường mỗi. Chỉ mục một trên vùng bộ lọc, bao gồm cả cột joinfield. Tiếp theo chúng ta sẽ điền chúng với các con số. tạo bảng dbo.table1 (id int identity (1,1) khóa chính , joinfield int , filterfield int ); go tạo bảng dbo.table2 (id int danh tính (1,1) khóa chính , joinfield int , filterfield int ); go tạo chỉ mục ix1 trên dbo.table1 (bộ lọc) bao gồm (joinfield); tạo chỉ mục ix2 trên dbo.table2 (bộ lọc) bao gồm (joinfield); go –

4

This blog post will probably answer your first question.

Đối với thứ hai của bạn, quét chỉ số có thể được lựa chọn bởi ưu trong một số tình huống. Off đỉnh đầu của tôi:

  • Nếu chỉ số này rất nhỏ
  • Nếu hầu hết các hàng trong chỉ mục sẽ được lựa chọn bởi các truy vấn

  • Nếu bạn đang sử dụng chức năng trong nơi khoản của truy vấn của bạn

Trong hai trường hợp đầu tiên, việc tối ưu hóa việc quét tìm kiếm sẽ hiệu quả hơn. Đối với trường hợp thứ ba, trình tối ưu hóa không có lựa chọn nào.

+0

Bài viết rất hay, cảm ơn bạn đã đăng nó. Vì vậy, ông nói rằng nếu cột đầu tiên được lập chỉ mục không được tham gia bởi truy vấn của tôi rằng nó có thể dẫn đến quét chỉ mục thay vì tìm kiếm? –

+1

Có. Btw, blog của anh ấy thực sự tốt cho việc học về các hoạt động bên trong của máy chủ sql. – womp

+0

Vâng, tôi rất ấn tượng với những gì tôi đọc ở đó. Thêm anh ấy vào danh sách của tôi. Cảm ơn đã chỉ cho tôi về phía anh ấy! –

2

1/A Hash Match có nghĩa là nó lấy một hash của các cột được sử dụng trong một phép nối bình đẳng, nhưng cần phải bao gồm tất cả các cột khác liên quan đến tham gia (for>, vv) để chúng có thể được kiểm tra. Đây là nơi các cột còn lại đi vào.

2/Chỉ mục Tìm kiếm có thể được thực hiện nếu nó có thể đi thẳng đến các hàng bạn muốn. Có lẽ bạn đang áp dụng một phép tính cho các cột và sử dụng nó? Sau đó, nó sẽ sử dụng chỉ mục như là một phiên bản nhỏ hơn của dữ liệu, nhưng vẫn sẽ cần phải kiểm tra mỗi hàng (áp dụng phép tính trên mỗi hàng).