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.
Nguồn
2010-01-21 01:09:13
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. –
@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ò. –
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 –