Được giới thiệu lần đầu trong SQL Server 2017 Enterprise Edition, một kết hợp thích ứng cho phép chuyển đổi thời gian chạy từ phép tham gia băm ở chế độ hàng loạt sang chế độ hàng có liên quan đến các vòng lặp lồng nhau được lập chỉ mục (áp dụng) trong thời gian chạy. Để ngắn gọn, tôi sẽ đề cập đến “phép nối được lập chỉ mục các vòng lồng nhau có tương quan” là một áp dụng trong suốt phần còn lại của bài viết này. Nếu bạn cần cập nhật về sự khác biệt giữa các vòng lặp lồng nhau và áp dụng, vui lòng xem bài viết trước của tôi.
Việc kết nối thích ứng có chuyển đổi từ tham gia băm để áp dụng trong thời gian chạy hay không phụ thuộc vào giá trị được gắn nhãn Các hàng ngưỡng thích ứng trên Tham gia thích ứng người điều hành kế hoạch thực hiện. Bài viết này cho biết cách hoạt động của phép nối thích ứng, bao gồm chi tiết về tính toán ngưỡng và bao gồm ý nghĩa của một số lựa chọn thiết kế được thực hiện.
Giới thiệu
Một điều tôi muốn bạn ghi nhớ trong suốt phần này là liên kết thích ứng luôn luôn bắt đầu thực thi dưới dạng tham gia băm chế độ hàng loạt. Điều này đúng ngay cả khi kế hoạch thực thi cho biết phép nối thích ứng dự kiến sẽ chạy khi áp dụng chế độ hàng.
Giống như bất kỳ phép nối băm nào, phép nối thích ứng đọc tất cả các hàng có sẵn trên đầu vào bản dựng của nó và sao chép dữ liệu cần thiết vào bảng băm. Hương vị chế độ hàng loạt của tham gia băm lưu trữ các hàng này ở định dạng được tối ưu hóa và phân vùng chúng bằng cách sử dụng một hoặc nhiều hàm băm. Khi đầu vào bản dựng đã được sử dụng, bảng băm được điền đầy đủ và được phân vùng, sẵn sàng cho phép nối băm bắt đầu kiểm tra các hàng phía thăm dò để tìm các kết quả phù hợp.
Đây là điểm mà phép nối thích ứng đưa ra quyết định tiếp tục với phép nối băm chế độ hàng loạt hoặc chuyển sang chế độ hàng áp dụng. Nếu số hàng trong bảng băm nhỏ hơn ngưỡng giá trị, phép nối chuyển thành áp dụng; nếu không, phép nối tiếp tục như một phép nối băm bằng cách bắt đầu đọc các hàng từ đầu vào thăm dò.
Nếu quá trình chuyển đổi sang một phép nối áp dụng xảy ra, kế hoạch thực thi sẽ không đọc lại các hàng được sử dụng để điền bảng băm để thúc đẩy hoạt động áp dụng. Thay vào đó, một thành phần bên trong được gọi là trình đọc bộ đệm thích ứng mở rộng các hàng đã được lưu trữ trong bảng băm và cung cấp chúng theo yêu cầu cho đầu vào bên ngoài của toán tử áp dụng. Có một khoản chi phí liên quan đến trình đọc bộ đệm thích ứng, nhưng nó thấp hơn nhiều so với chi phí tua lại hoàn toàn đầu vào bản dựng.
Chọn một tham gia thích ứng
Tối ưu hóa truy vấn liên quan đến một hoặc nhiều giai đoạn thăm dò logic và thực hiện vật lý các lựa chọn thay thế. Ở mỗi giai đoạn, khi trình tối ưu hóa khám phá các tùy chọn vật lý cho một lôgic tham gia, nó có thể xem xét cả tham gia băm chế độ hàng loạt và chế độ hàng đều áp dụng các lựa chọn thay thế.
Nếu một trong các tùy chọn kết hợp vật lý đó tạo thành một phần của giải pháp rẻ nhất được tìm thấy trong giai đoạn hiện tại— và loại kết hợp khác có thể cung cấp các thuộc tính logic bắt buộc tương tự — trình tối ưu hóa đánh dấu nhóm tham gia logic là có khả năng thích hợp cho một tham gia thích ứng. Nếu không, việc xem xét tham gia thích ứng kết thúc ở đây (và không có sự kiện mở rộng tham gia thích ứng nào được kích hoạt).
Hoạt động bình thường của trình tối ưu hóa có nghĩa là giải pháp rẻ nhất được tìm thấy sẽ chỉ bao gồm một trong các tùy chọn kết hợp vật lý — băm hoặc áp dụng, tùy theo tùy chọn nào có chi phí ước tính thấp nhất. Điều tiếp theo mà trình tối ưu hóa làm là xây dựng và chi phí triển khai mới loại kết hợp không phải được chọn là rẻ nhất.
Vì giai đoạn tối ưu hóa hiện tại đã kết thúc với một giải pháp rẻ nhất được tìm thấy, một vòng thăm dò và triển khai nhóm đơn đặc biệt được thực hiện cho phép nối thích ứng. Cuối cùng, trình tối ưu hóa tính toán ngưỡng thích ứng .
Nếu bất kỳ công việc nào trước đó không thành công, sự kiện mở rộng adaptive_join_skipped sẽ được kích hoạt có lý do.
Nếu quá trình kết hợp thích ứng thành công, một Concat toán tử được thêm vào kế hoạch nội bộ phía trên băm và áp dụng các lựa chọn thay thế với trình đọc bộ đệm thích ứng và bất kỳ bộ điều hợp chế độ hàng / lô bắt buộc nào. Hãy nhớ rằng chỉ một trong các lựa chọn thay thế tham gia sẽ thực thi trong thời gian chạy, tùy thuộc vào số lượng hàng thực sự gặp phải so với ngưỡng thích ứng.
The Concat toán tử và các lựa chọn thay thế băm / áp dụng riêng lẻ thường không được hiển thị trong kế hoạch thực thi cuối cùng. Thay vào đó, chúng tôi được giới thiệu với một Tham gia thích ứng nhà điều hành. Đây chỉ là một quyết định trình bày — Concat và các phép nối vẫn hiện diện trong mã do công cụ thực thi SQL Server chạy. Bạn có thể tìm thêm thông tin chi tiết về vấn đề này trong phần Phụ lục và phần Đọc liên quan của bài viết này.
Ngưỡng thích ứng
Một ứng dụng thường rẻ hơn một tham gia băm cho một số lượng hàng lái xe nhỏ hơn. Tham gia băm có thêm chi phí khởi động để xây dựng bảng băm của nó nhưng chi phí trên mỗi hàng thấp hơn khi bắt đầu thăm dò các kết quả phù hợp.
Nhìn chung, có một điểm mà chi phí ước tính của một phép tham gia áp dụng và hàm băm sẽ bằng nhau. Ý tưởng này đã được minh họa một cách độc đáo bởi Joe Sack trong bài viết của anh ấy, Giới thiệu các phép ghép nối thích ứng với chế độ hàng loạt:
Tính toán ngưỡng
Tại thời điểm này, trình tối ưu hóa có một ước tính duy nhất cho số hàng nhập đầu vào xây dựng của phép nối băm và áp dụng các lựa chọn thay thế. Nó cũng có chi phí ước tính của các toán tử băm và áp dụng nói chung.
Điều này cho chúng ta một điểm duy nhất ở rìa bên phải của các đường màu cam và màu xanh lam trong sơ đồ trên. Trình tối ưu hóa cần một điểm tham chiếu khác cho mỗi loại kết hợp để nó có thể "vẽ các đường" và tìm giao điểm (nó không vẽ các đường theo nghĩa đen, nhưng bạn có ý tưởng).
Để tìm điểm thứ hai cho các dòng, trình tối ưu hóa yêu cầu cả hai kết hợp để tạo ra một ước tính chi phí mới dựa trên một bản số đầu vào khác nhau (và giả định). Nếu ước tính số lượng hàng đầu tiên là hơn 100 hàng, nó yêu cầu các liên kết ước tính chi phí mới cho một hàng. Nếu bản số ban đầu nhỏ hơn hoặc bằng 100 hàng, thì điểm thứ hai dựa trên bản số đầu vào là 10.000 hàng (do đó, có một phạm vi đủ phù hợp để ngoại suy).
Trong mọi trường hợp, kết quả là hai chi phí và số hàng khác nhau cho mỗi loại kết hợp, cho phép các dòng được “vẽ”.
Công thức Giao điểm
Tìm giao điểm của hai đường dựa trên hai điểm của mỗi đường là một bài toán có một số giải pháp phổ biến. SQL Server sử dụng một dựa trên yếu tố quyết định như được mô tả trên Wikipedia:
ở đâu:
Dòng đầu tiên được xác định bởi các điểm (x 1 , y 1 ) và (x 2 , y 2 ). Dòng thứ hai được cho bởi các điểm (x 3 , y 3 ) và (x 4 , y 4 ). Giao lộ là (P x , P y ).
Lược đồ của chúng tôi có số hàng trên trục x và chi phí ước tính trên trục y. Chúng tôi quan tâm đến số hàng nơi các đường giao nhau. Điều này được đưa ra bởi công thức cho P x . Nếu chúng tôi muốn biết chi phí ước tính tại giao lộ, nó sẽ là P y .
Đối với P x , chi phí ước tính của các giải pháp áp dụng và liên kết băm sẽ bằng nhau. Đây là ngưỡng thích ứng mà chúng tôi cần.
Một ví dụ đã làm việc
Dưới đây là một ví dụ sử dụng cơ sở dữ liệu mẫu AdventureWorks2017 và thủ thuật lập chỉ mục sau của Itzik Ben-Gan để xem xét vô điều kiện việc thực thi chế độ hàng loạt:
- Mánh khóe của Itzik - Kiểm tra truy vấnSELECT SOH.SubTotalFROM Sales.SalesOrderHeader AS SOHJOIN Sales.SalesOrderDetail AS SOD ON SOD.SalesOrderID =SOH.SalesOrderIDWHERE SOH.SalesOrderID <=75123;
Kế hoạch thực hiện hiển thị một kết hợp thích ứng với ngưỡng 1502,07 hàng:
Số hàng ước tính thúc đẩy kết hợp thích ứng là 31.465 .
Chi phí tham gia
Trong trường hợp đơn giản này, chúng tôi có thể tìm chi phí cây con ước tính cho băm và áp dụng các lựa chọn thay thế tham gia bằng cách sử dụng gợi ý:
- HashSELECT SOH.SubTotalFROM Sales.SalesOrderHeader AS SOHJOIN Sales.SalesOrderDetail AS SOD ON SOD.SalesOrderID =SOH.SalesOrderIDWHERE SOH.SalesOrderID <=75123OPTION (HASH JOIN, MAXDOP 1);
- ApplySELECT SOH.SubTotalFROM Sales.SalesOrderHeader AS SOHJOIN Sales.SalesOrderDetail AS SOD ON SOD.SalesOrderID =SOH.SalesOrderIDWHERE SOH.SalesOrderID <=75123OPTION (LOOP JOIN, MAXDOP 1);
Điều này cung cấp cho chúng tôi một điểm trên dòng cho mỗi loại kết hợp:
- 31.465 hàng
- Chi phí băm 1.05083
- Áp dụng chi phí 10.0552
Điểm thứ hai trên đường
Vì số lượng hàng ước tính là hơn 100, điểm tham chiếu thứ hai đến từ các ước tính nội bộ đặc biệt dựa trên một hàng đầu vào kết hợp. Thật không may, không có cách nào dễ dàng để có được con số chi phí chính xác cho phép tính nội bộ này (tôi sẽ nói thêm về vấn đề này ngay sau đây).
Hiện tại, tôi sẽ chỉ hiển thị cho bạn các con số chi phí (sử dụng độ chính xác nội bộ đầy đủ thay vì sáu con số quan trọng được trình bày trong kế hoạch thực hiện):
- Một hàng (tính toán nội bộ)
- Chi phí băm 0,999027422729
- Áp dụng chi phí 0,547927305023
- 31.465 hàng
- Chi phí băm 1,05082787359
- Áp dụng chi phí 10.0552890166
Như mong đợi, phép nối áp dụng rẻ hơn phép băm cho số lượng đầu vào nhỏ nhưng đắt hơn nhiều đối với số lượng hàng dự kiến là 31.465 hàng.
Tính toán giao lộ
Việc cắm các con số về số lượng và chi phí này vào công thức giao điểm đường thẳng sẽ cho bạn những kết quả sau:
- Điểm băm (x =cardinality; y =cost) DECLARE @ x1 float =1, @ y1 float =0.999027422729, @ x2 float =31465, @ y2 float =1.05082787359; - Áp dụng điểm (x =cardinality; y =cost) DECLARE @ x3 float =1, @ y3 float =0.547927305023, @ x4 float =31465, @ y4 float =10.0552890166; - Công thức:Ngưỡng CHỌN =((@ x1 * @ y2 - @ y1 * @ x2) * (@ x3 - @ x4) - (@ x1 - @ x2) * (@ x3 * @ y4 - @ y3 * @ x4 )) / ((@ x1 - @ x2) * (@ y3 - @ y4) - (@ y1 - @ y2) * (@ x3 - @ x4)); - Trả về 1502.06521571273
Làm tròn đến sáu con số quan trọng, kết quả này khớp với 1502,07 các hàng được hiển thị trong kế hoạch thực thi kết hợp thích ứng:
Khiếm khuyết hay thiết kế?
Hãy nhớ rằng, SQL Server cần bốn điểm để "vẽ" số hàng so với đường chi phí để tìm ngưỡng tham gia thích ứng. Trong trường hợp hiện tại, điều này có nghĩa là tìm ước tính chi phí cho các cấp số một hàng và 31.465 hàng cho cả triển khai áp dụng và liên kết băm.
Trình tối ưu hóa gọi một quy trình có tên sqllang!CuNewJoinEstimate
để tính toán bốn chi phí này cho một liên kết thích ứng. Đáng buồn thay, không có cờ theo dõi hoặc các sự kiện mở rộng để cung cấp một cái nhìn tổng quan hữu ích về hoạt động này. Các cờ theo dõi thông thường được sử dụng để điều tra hành vi của trình tối ưu hóa và chi phí hiển thị không hoạt động ở đây (xem Phụ lục nếu bạn muốn biết thêm chi tiết).
Cách duy nhất để có được ước tính chi phí một hàng là đính kèm trình gỡ lỗi và đặt điểm ngắt sau lần gọi thứ tư tới CuNewJoinEstimate
trong mã cho sqllang!CardSolveForSwitch
. Tôi đã sử dụng WinDbg để lấy ngăn xếp cuộc gọi này trên SQL Server 2019 CU12:
Tại thời điểm này trong mã, chi phí dấu chấm động có độ chính xác kép được lưu trữ trong bốn vị trí bộ nhớ được trỏ đến bởi các địa chỉ tại rsp+b0
, rsp+d0
, rsp+30
và rsp+28
(trong đó rsp
là một thanh ghi CPU và các hiệu số ở dạng thập lục phân):
Số chi phí cây con của toán tử được hiển thị khớp với những con số được sử dụng trong công thức tính ngưỡng tham gia thích ứng.
Giới thiệu về Ước tính Chi phí Một Hàng đó
Bạn có thể nhận thấy chi phí cây con ước tính cho các phép nối một hàng có vẻ khá cao đối với khối lượng công việc liên quan đến việc tham gia một hàng:
- Một hàng
- Chi phí băm 0,999027422729
- Áp dụng chi phí 0,547927305023
Nếu bạn cố gắng tạo kế hoạch thực thi đầu vào một hàng cho phép nối băm và áp dụng các ví dụ, bạn sẽ thấy nhiều chi phí cây con ước tính thấp hơn khi tham gia so với chi phí được hiển thị ở trên. Tương tự như vậy, việc chạy truy vấn ban đầu với mục tiêu hàng là một (hoặc số hàng kết hợp đầu ra dự kiến cho đầu vào của một hàng) cũng sẽ tạo ra chi phí ước tính cách thấp hơn hiển thị.
Lý do là CuNewJoinEstimate
quy trình ước tính một hàng theo cách mà tôi nghĩ rằng hầu hết mọi người sẽ không thấy trực quan.
Chi phí cuối cùng được tạo thành từ ba thành phần chính:
- Chi phí cây con đầu vào của bản dựng
- Chi phí địa phương của việc tham gia
- Chi phí cây con đầu vào của đầu dò
Mục 2 và 3 tùy thuộc vào kiểu tham gia. Đối với phép tham gia băm, chúng tính đến chi phí đọc tất cả các hàng từ đầu vào thăm dò, khớp chúng (hoặc không) với một hàng trong bảng băm và chuyển kết quả cho toán tử tiếp theo. Đối với đơn đăng ký, chi phí bao gồm một lần tìm kiếm đầu vào thấp hơn cho phép nối, chi phí nội bộ của chính phép nối và trả về các hàng đã khớp cho toán tử mẹ.
Không có điều nào trong số này là bất thường hoặc đáng ngạc nhiên.
Sự bất ngờ về chi phí
Điều bất ngờ đến ở mặt xây dựng của phép nối (mục 1 trong danh sách). Người ta có thể mong đợi trình tối ưu hóa thực hiện một số tính toán ưa thích để chia tỷ lệ chi phí cây con đã được tính toán cho 31.465 hàng xuống một hàng trung bình hoặc tương tự như vậy.
Trên thực tế, cả ước tính hàm băm và áp dụng liên kết một hàng chỉ cần sử dụng toàn bộ chi phí của cây con cho ban đầu ước tính cardinality của 31.465 hàng. Trong ví dụ đang chạy của chúng tôi, “cây con” này là 0,54456 chi phí của tìm kiếm chỉ mục được phân nhóm ở chế độ hàng loạt trên bảng tiêu đề:
Nói rõ hơn:chi phí ước tính phía bản dựng cho các lựa chọn thay thế kết hợp một hàng sử dụng chi phí đầu vào được tính cho 31.465 hàng. Điều đó sẽ khiến bạn hơi kỳ quặc.
Xin nhắc lại, chi phí một hàng được tính toán bởi CuNewJoinEstimate
như sau:
- Một hàng
- Chi phí băm 0,999027422729
- Áp dụng chi phí 0,547927305023
Bạn có thể thấy tổng chi phí áp dụng (~ 0,54793) bị chi phối bởi 0,54456 chi phí cây con bên xây dựng, với một số tiền bổ sung nhỏ cho tìm kiếm bên trong duy nhất, xử lý số lượng nhỏ các hàng kết quả trong phép nối và chuyển chúng cho toán tử mẹ.
Chi phí tham gia băm một hàng ước tính cao hơn bởi vì phía thăm dò của kế hoạch bao gồm quét chỉ mục đầy đủ, trong đó tất cả các hàng kết quả phải đi qua tham gia. Tổng chi phí của phép tham gia băm một hàng thấp hơn một chút so với chi phí 1.05095 ban đầu cho ví dụ 31.465 hàng vì hiện chỉ có một hàng trong bảng băm.
Hàm ý
Người ta mong đợi ước tính kết hợp một hàng một phần dựa trên chi phí phân phối một hàng cho đầu vào tham gia lái xe. Như chúng ta đã thấy, đây không phải là trường hợp của phép nối thích ứng:cả các lựa chọn thay thế áp dụng và băm đều được giải quyết với chi phí ước tính đầy đủ cho 31.465 hàng. Phần còn lại của phép nối có giá khá cao như người ta mong đợi đối với đầu vào bản dựng một hàng.
Sự sắp xếp kỳ lạ về mặt trực giác này là lý do tại sao rất khó (có lẽ là không thể) để đưa ra một kế hoạch thực hiện phản ánh các chi phí đã tính toán. Chúng tôi cần phải xây dựng một kế hoạch phân phối 31.465 hàng cho đầu vào liên kết phía trên nhưng tính phí chính liên kết và đầu vào bên trong của nó như thể chỉ có một hàng. Một câu hỏi khó.
Tác dụng của tất cả những điều này là nâng điểm ngoài cùng bên trái trên biểu đồ hai đường giao nhau lên trục y. Điều này ảnh hưởng đến độ dốc của đường và do đó ảnh hưởng đến điểm giao nhau.
Một hiệu ứng thực tế khác là ngưỡng tham gia thích ứng được tính toán hiện phụ thuộc vào ước tính bản số ban đầu ở đầu vào xây dựng hàm băm, như Joe Obbish đã lưu ý trong bài đăng trên blog năm 2017 của anh ấy. Ví dụ:nếu chúng ta thay đổi WHERE
mệnh đề trong truy vấn kiểm tra tới SOH.SalesOrderID <= 55000
, ngưỡng thích ứng giảm từ 1502.07 đến 1259.8 mà không thay đổi hàm băm của kế hoạch truy vấn. Cùng một kế hoạch, ngưỡng khác nhau.
Điều này phát sinh bởi vì, như chúng ta đã thấy, ước tính chi phí nội bộ cho một hàng phụ thuộc vào chi phí đầu vào của bản dựng cho ước tính số lượng ban đầu. Điều này có nghĩa là các ước tính phía xây dựng ban đầu khác nhau sẽ cung cấp một “mức tăng” trục y khác cho ước tính một hàng. Đổi lại, đường sẽ có độ dốc khác và giao điểm khác.
Trực giác sẽ đề xuất ước tính một hàng cho cùng một phép nối phải luôn cho cùng một giá trị bất kể ước tính số lượng khác trên dòng (với cùng một phép nối chính xác có cùng thuộc tính và kích thước hàng có mối quan hệ gần tuyến tính giữa việc lái xe hàng và chi phí). Đây không phải là trường hợp của tham gia thích ứng.
Theo thiết kế?
Tôi có thể tự tin cho bạn biết SQL Server làm gì khi tính toán ngưỡng tham gia thích ứng. Tôi không có bất kỳ thông tin chi tiết đặc biệt nào về tại sao nó thực hiện theo cách này.
Tuy nhiên, có một số lý do để cho rằng sự sắp xếp này là có chủ ý và được thực hiện sau khi xem xét và phản hồi từ thử nghiệm. Phần còn lại của phần này trình bày một số suy nghĩ của tôi về khía cạnh này.
Tham gia thích ứng không phải là sự lựa chọn thẳng thắn giữa tham gia băm áp dụng bình thường và tham gia băm chế độ hàng loạt. Một phép nối thích ứng luôn bắt đầu bằng cách điền đầy đủ vào bảng băm. Chỉ khi công việc này hoàn tất thì mới có quyết định chuyển sang áp dụng triển khai hay không.
Vào thời điểm này, chúng tôi đã phải gánh chịu chi phí đáng kể có thể xảy ra bằng cách điền và phân vùng tham gia băm trong bộ nhớ. Điều này có thể không quan trọng lắm đối với trường hợp một hàng, nhưng nó ngày càng trở nên quan trọng hơn khi số lượng thẻ số tăng lên. “Sự gia tăng” bất ngờ có thể là một cách để kết hợp những thực tế này vào tính toán trong khi vẫn giữ được chi phí tính toán hợp lý.
Mô hình chi phí của SQL Server từ lâu đã có một chút thành kiến đối với việc tham gia các vòng lặp lồng nhau, được cho là có một số biện minh. Ngay cả trường hợp áp dụng được lập chỉ mục lý tưởng cũng có thể chậm trong thực tế nếu dữ liệu cần thiết chưa có trong bộ nhớ và hệ thống con I / O không nhấp nháy, đặc biệt là với kiểu truy cập hơi ngẫu nhiên. Ví dụ:số lượng bộ nhớ hạn chế và I / O chậm chạp sẽ không hoàn toàn xa lạ với người dùng các công cụ cơ sở dữ liệu dựa trên đám mây cấp thấp hơn.
Thử nghiệm thực tế có thể xảy ra trong những môi trường như vậy cho thấy một phép tham gia thích ứng với chi phí trực quan quá nhanh để chuyển đổi sang đơn đăng ký. Lý thuyết đôi khi chỉ là lý thuyết tuyệt vời.
Tuy nhiên, tình hình hiện tại không phải là lý tưởng; vào bộ nhớ đệm một kế hoạch dựa trên ước tính số lượng thấp bất thường sẽ tạo ra một phép nối thích ứng miễn cưỡng chuyển sang áp dụng hơn nhiều so với ước tính ban đầu lớn hơn. Đây là một loạt các vấn đề về độ nhạy thông số, nhưng đây sẽ là một vấn đề mới được xem xét về loại này đối với nhiều người trong chúng ta.
Bây giờ, nó cũng có thể sử dụng toàn bộ chi phí cây con đầu vào của bản dựng cho điểm ngoài cùng bên trái của các đường chi phí giao nhau chỉ đơn giản là một lỗi hoặc sự giám sát chưa được điều chỉnh. Cảm giác của tôi là việc triển khai hiện tại có lẽ là một sự thỏa hiệp thực tế có chủ ý, nhưng bạn cần ai đó có quyền truy cập vào tài liệu thiết kế và mã nguồn để biết chắc chắn.
Tóm tắt
Một phép nối thích ứng cho phép SQL Server chuyển đổi từ phép nối băm chế độ hàng loạt sang một phép tham gia áp dụng sau khi bảng băm đã được điền đầy đủ. Nó đưa ra quyết định này bằng cách so sánh số hàng trong bảng băm với ngưỡng thích ứng được tính toán trước.
Ngưỡng được tính bằng cách dự đoán vị trí áp dụng và chi phí tham gia băm là bằng nhau. Để tìm ra điểm này, SQL Server tạo ước tính chi phí kết hợp nội bộ thứ hai cho một bản số đầu vào bản dựng khác — thông thường, một hàng.
Đáng ngạc nhiên là chi phí ước tính cho ước tính một hàng bao gồm toàn bộ chi phí cây con bên tạo cho ước tính số lượng bản gốc (không được chia tỷ lệ thành một hàng). Điều này có nghĩa là giá trị ngưỡng phụ thuộc vào ước tính bản số ban đầu ở đầu vào bản dựng.
Do đó, một phép nối thích ứng có thể có giá trị ngưỡng thấp bất ngờ, có nghĩa là phép nối thích ứng ít có khả năng chuyển khỏi phép nối băm hơn nhiều. Không rõ hành vi này có phải do thiết kế hay không.
Đọc liên quan
- Giới thiệu phần tham gia thích ứng với chế độ hàng loạt của Joe Sack
- Hiểu các Kết hợp Thích ứng trong tài liệu sản phẩm
- Nội bộ tham gia thích ứng của Dima Pilugin
- Làm thế nào để Kết hợp Thích ứng với Chế độ Hàng loạt hoạt động? trên Stack Exchange của quản trị viên cơ sở dữ liệu của Erik Darling
- Hồi quy tham gia thích ứng của Joe Obbish
- Nếu bạn muốn tham gia thích ứng, bạn cần chỉ mục rộng hơn và lớn hơn có tốt hơn không? bởi Erik Darling
- Đánh giá tham số:Tham gia thích ứng của Brent Ozar
- Hỏi và đáp về xử lý truy vấn thông minh của Joe Sack
Phụ lục
Phần này bao gồm một số khía cạnh liên kết thích ứng mà rất khó để đưa vào văn bản chính một cách tự nhiên.
Kế hoạch thích ứng mở rộng
Bạn có thể thử xem bản trình bày trực quan của kế hoạch nội bộ bằng cách sử dụng cờ theo dõi không có tài liệu 9415, như được cung cấp bởi Dima Pilugin trong bài viết nội bộ tham gia thích ứng tuyệt vời của anh ấy được liên kết ở trên. Với cờ này đang hoạt động, kế hoạch tham gia thích ứng cho ví dụ đang chạy của chúng tôi sẽ trở thành như sau:
Đây là một trình bày hữu ích để hỗ trợ sự hiểu biết, nhưng nó không hoàn toàn chính xác, đầy đủ hoặc nhất quán. Ví dụ:Table Spool không tồn tại — nó là đại diện mặc định cho trình đọc bộ đệm thích ứng đọc các hàng trực tiếp từ bảng băm chế độ hàng loạt.
Các thuộc tính toán tử và các ước lượng về số lượng cũng có một chút ở khắp nơi. Đầu ra từ trình đọc bộ đệm thích ứng (“spool”) phải là 31.465 hàng, không phải 121.317. Chi phí cây con của đơn đăng ký bị giới hạn không chính xác bởi chi phí điều hành viên chính. Điều này là bình thường đối với kế hoạch chương trình, nhưng nó không có ý nghĩa gì trong bối cảnh tham gia thích ứng.
Cũng có những mâu thuẫn khác — quá nhiều để liệt kê một cách hữu ích — nhưng điều đó có thể xảy ra với cờ theo dõi không có tài liệu. Kế hoạch mở rộng được hiển thị ở trên không dành cho người dùng cuối sử dụng, vì vậy có lẽ điều đó không hoàn toàn đáng ngạc nhiên. Thông điệp ở đây là không phụ thuộc quá nhiều vào các con số và thuộc tính được hiển thị trong biểu mẫu không có giấy tờ này.
Tôi cũng nên đề cập đến việc thông qua nhà điều hành kế hoạch tham gia thích ứng tiêu chuẩn đã hoàn thành không hoàn toàn không có các vấn đề về tính nhất quán của riêng nó. Những điều này hoàn toàn bắt nguồn từ các chi tiết ẩn.
Ví dụ:các thuộc tính tham gia thích ứng được hiển thị đến từ hỗn hợp của Concat cơ bản , Hash Join và Áp dụng các toán tử. Bạn có thể thấy thực thi chế độ hàng loạt báo cáo kết hợp thích ứng cho phép tham gia vòng lặp lồng nhau (điều này là không thể) và thời gian đã trôi qua được hiển thị thực sự được sao chép từ Concat ẩn , không phải tham gia cụ thể được thực thi trong thời gian chạy.
Những kẻ tình nghi thông thường
Chúng tôi có thể nhận một số thông tin hữu ích từ các loại cờ theo dõi không có tài liệu thường được sử dụng để xem đầu ra của trình tối ưu hóa. Ví dụ:
SELECT SOH.SubTotalFROM Sales.SalesOrderHeader AS SOHJOIN Sales.SalesOrderDetail AS SOD ON SOD.SalesOrderID =SOH.SalesOrderIDWHERE SOH.SalesOrderID <=75123OPTION (QUERYTRACEON 3604, QUERYTRACEON 8607, QUERYTRACEON 8607, Đầu ra (được chỉnh sửa nhiều để dễ đọc): *** Cây đầu ra:***
Thẻ PhyOp_ExecutionModeAdapter (BatchToRow) =121317 Chi phí =1.05095
- Thẻ PhyOp_Concat (lô) =121317 Chi phí =1,05325
- Thẻ PhyOp_HashJoinx_jtInner (lô) =121317 Chi phí =1.05083
- Thẻ PhyOp_Range Sales.SalesOrderHeader =31465 Chi phí =0,54456
- Thẻ PhyOp_Filter (lô) =121317 Chi phí =0,397185
- Thẻ PhyOp_Range Sales.SalesOrderDetail =121317 Chi phí =0,338953
- Thẻ PhyOp_ExecutionModeAdapter (RowToBatch) =121317 Cost =10,0798
- Thẻ PhyOp_Apply =121317 Chi phí =10.0553
- Thẻ PhyOp_ExecutionModeAdapter (BatchToRow) =31465 Chi phí =0,544623
- Thẻ PhyOp_Range Sales.SalesOrderHeader =31465 Chi phí =0,54456 [** 3 **]
- Thẻ PhyOp_Filter =3.85562 Chi phí =9.00356
- Thẻ PhyOp_Range Sales.SalesOrderDetail =3.85562 Chi phí =8.94533
- Thẻ PhyOp_ExecutionModeAdapter (BatchToRow) =31465 Chi phí =0,544623
- Thẻ PhyOp_Apply =121317 Chi phí =10.0553
Điều này cung cấp một số thông tin chi tiết về chi phí ước tính cho trường hợp bản số đầy đủ với hàm băm và áp dụng các lựa chọn thay thế mà không cần viết các truy vấn riêng biệt và sử dụng gợi ý. Như đã đề cập trong văn bản chính, các cờ theo dõi này không hiệu quả trong CuNewJoinEstimate
, vì vậy chúng tôi không thể xem trực tiếp các phép tính lặp lại cho trường hợp 31.465 hàng hoặc bất kỳ chi tiết nào cho ước tính một hàng theo cách này.
Kết hợp tham gia và tham gia băm chế độ hàng
Các phép nối thích ứng chỉ cung cấp sự chuyển đổi từ phép nối băm ở chế độ hàng loạt sang chế độ hàng được áp dụng. Để biết lý do tại sao tham gia băm chế độ hàng không được hỗ trợ, hãy xem Hỏi và đáp về xử lý truy vấn thông minh trong phần Đọc liên quan. Nói tóm lại, người ta nghĩ rằng các phép tham gia băm chế độ hàng sẽ quá dễ bị thoái lui hiệu suất.
Chuyển sang kết hợp hợp nhất chế độ hàng sẽ là một tùy chọn khác, nhưng trình tối ưu hóa hiện không xem xét điều này. Theo tôi hiểu, nó khó có thể được mở rộng theo hướng này trong tương lai.
Một số cân nhắc cũng giống như đối với tham gia băm chế độ hàng. Ngoài ra, các kế hoạch liên kết hợp nhất có xu hướng ít được hoán đổi cho nhau dễ dàng hơn với tham gia băm, ngay cả khi chúng tôi tự giới hạn mình ở liên kết hợp nhất được lập chỉ mục (không có sắp xếp rõ ràng).
Cũng có sự khác biệt lớn hơn giữa băm và áp dụng so với giữa băm và hợp nhất. Cả băm và hợp nhất đều phù hợp với đầu vào lớn hơn và áp dụng phù hợp hơn với đầu vào dẫn động nhỏ hơn. Tham gia hợp nhất không dễ dàng song song như tham gia băm và không mở rộng quy mô cũng như tăng số lượng chuỗi.
Với động lực cho các liên kết thích ứng là để đối phó tốt hơn với đáng kể kích thước đầu vào khác nhau — và chỉ tham gia băm hỗ trợ xử lý chế độ hàng loạt — lựa chọn băm hàng loạt so với áp dụng hàng là lựa chọn tự nhiên hơn. Cuối cùng, việc có ba lựa chọn tham gia thích ứng sẽ làm phức tạp đáng kể việc tính toán ngưỡng cho khả năng thu được rất ít.