Hoạt động vật lý liên kết: Nó có đảm bảo thứ tự thực hiện không?


12

Trong SQL tiêu chuẩn, kết quả của a union allkhông được đảm bảo theo bất kỳ thứ tự nào. Vì vậy, một cái gì đó như:

select 'A' as c union all select 'B'

Có thể trả về hai hàng theo bất kỳ thứ tự nào (mặc dù, trên thực tế trên bất kỳ cơ sở dữ liệu nào tôi biết, 'A' sẽ đến trước 'B').

Trong SQL Server, điều này biến thành một kế hoạch thực hiện bằng cách sử dụng một hoạt động vật lý "nối".

Tôi có thể dễ dàng tưởng tượng rằng hoạt động nối sẽ quét các đầu vào của nó, trả về bất kỳ đầu vào nào có sẵn các bản ghi. Tuy nhiên, tôi đã tìm thấy tuyên bố sau trên web ( tại đây ):

Bộ xử lý truy vấn sẽ thực hiện kế hoạch này theo thứ tự các toán tử xuất hiện trong kế hoạch, đầu tiên là đầu tiên và cuối cùng là cuối cùng.

Câu hỏi: Điều này có đúng trong thực tế không? Điều này có được đảm bảo là đúng không?

Tôi không tìm thấy bất kỳ tài liệu tham khảo nào trong tài liệu của Microsoft rằng các đầu vào được quét theo thứ tự, từ đầu đến cuối. Mặt khác, bất cứ khi nào tôi thử chạy nó, kết quả cho thấy rằng các đầu vào thực sự được xử lý theo thứ tự.

Có cách nào để động cơ xử lý nhiều hơn một đầu vào cùng một lúc không? Các thử nghiệm của tôi (sử dụng các biểu thức phức tạp hơn nhiều so với hằng số) trên máy 8 lõi được kích hoạt song song và hầu hết các truy vấn đều tận dụng tính song song.

Câu trả lời:


10

Không , không có tài liệu nào từ Microsoft đảm bảo hành vi, do đó nó không được bảo đảm .

Ngoài ra, giả sử rằng bài viết Cuộc nói chuyện đơn giản là chính xác và toán tử vật lý Kết nối luôn xử lý các đầu vào theo thứ tự được hiển thị trong kế hoạch (rất có thể là đúng), sau đó không đảm bảo rằng SQL Server sẽ luôn tạo các kế hoạch giữ nguyên thứ tự giữa văn bản truy vấn và kế hoạch truy vấn, bạn chỉ khá hơn một chút.

Chúng tôi có thể điều tra điều này hơn nữa mặc dù. Nếu trình tối ưu hóa truy vấn có thể sắp xếp lại đầu vào toán tử Ghép, sẽ tồn tại các hàng trong DMV không có giấy tờ, sys.dm_exec_query_transformation_statstương ứng với tối ưu hóa đó.

SELECT * FROM sys.dm_exec_query_transformation_stats 
    WHERE name LIKE '%CON%' OR name LIKE '%UNIA%'

Trên SQL Server 2012 Enterprise Edition, điều này tạo ra 24 hàng. Bỏ qua các kết quả khớp sai cho các phép biến đổi liên quan đến hằng số, có một phép biến đổi liên quan đến Toán tử vật lý nối UNIAtoCON(Liên kết tất cả với phép nối). Vì vậy, ở cấp độ toán tử vật lý, có vẻ như một khi toán tử ghép được chọn, nó sẽ được xử lý theo thứ tự của toán tử Union All logic mà nó được lấy từ đó.


Trong thực tế điều đó không hoàn toàn đúng. Viết lại tối ưu hóa sau có thể sắp xếp lại các đầu vào thành toán tử Ghép vật lý sau khi tối ưu hóa dựa trên chi phí đã hoàn thành. Một ví dụ xảy ra khi Ghép nối phải tuân theo mục tiêu hàng (vì vậy có thể cần đọc từ đầu vào rẻ hơn trước). Xem UNION ALLTối ưu hóa của Paul White để biết thêm chi tiết.

Việc viết lại vật lý muộn này có chức năng lên đến và bao gồm cả SQL Server 2008 R2, nhưng hồi quy có nghĩa là nó không còn được áp dụng cho SQL Server 2012 trở lên. Một bản sửa lỗi đã được ban hành để khôi phục việc viết lại này cho SQL Server 2014 trở lên (không phải 2012) với các hotfix tối ưu hóa truy vấn được bật (ví dụ: cờ theo dõi 4199).


Nhưng về toán tử Liên minh logic Tất cả ( UNIA)? Có một sự UNIAReorderInputschuyển đổi, có thể sắp xếp lại các đầu vào. Ngoài ra còn có hai toán tử vật lý có thể được sử dụng để triển khai Liên minh hợp lý UNIAtoCONUNIAtoMERGE(Liên minh tất cả để hợp nhất).

Do đó, trình tối ưu hóa truy vấn có thể sắp xếp lại các đầu vào cho a UNION ALL; tuy nhiên, nó dường như không phải là một biến đổi phổ biến (không sử dụng UNIAReorderInputstrên Máy chủ SQL mà tôi có thể truy cập được. Chúng tôi không biết các trường hợp sẽ sử dụng trình tối ưu hóa UNIAReorderInputs; mặc dù nó chắc chắn được sử dụng khi hướng dẫn hoặc sử dụng kế hoạch gợi ý kế hoạch được sử dụng để buộc một kế hoạch được tạo bằng cách sử dụng các mục nhập được sắp xếp lại theo thứ tự vật lý được đề cập ở trên.

Có cách nào để động cơ xử lý nhiều hơn một đầu vào cùng một lúc không?

Toán tử vật lý liên kết có thể tồn tại trong một phần song song của kế hoạch. Với một số khó khăn, tôi đã có thể tạo ra một kế hoạch với các kết nối song song bằng cách sử dụng truy vấn sau:

SELECT userid, regdate  FROM (  --Users table is around 3mil rows
    SELECT  userid, RegDate FROM users WHERE userid > 1000000
    UNION 
    SELECT  userid, RegDate FROM users WHERE userid < 1000000
    UNION all
    SELECT userid, RegDate FROM users WHERE userid < 2000000
    ) d ORDER BY RegDate OPTION (RECOMPILE)

Vì vậy, theo nghĩa chặt chẽ nhất, toán tử Ghép nối vật lý dường như luôn luôn xử lý các đầu vào theo một cách nhất quán (đầu tiên đầu tiên, thứ hai dưới cùng); tuy nhiên, trình tối ưu hóa có thể chuyển đổi thứ tự của các đầu vào trước khi chọn toán tử vật lý hoặc sử dụng liên kết Hợp nhất thay vì Ghép nối.


8

Theo Craig Freedman , thứ tự thực hiện cho toán tử ghép được đảm bảo.

Từ bài đăng trên blog của anh ấy Xem Kế hoạch truy vấn trên Blog MSDN:

Lưu ý rằng khi một nhà điều hành có nhiều hơn một con, thứ tự của các con có vấn đề. Đứa trẻ trên cùng là đứa trẻ đầu tiên trong khi đứa trẻ cuối cùng là đứa thứ hai. Toán tử ghép xử lý các con theo thứ tự này.

Và từ sách trực tuyến Tham khảo các nhà khai thác logic và vật lý

Toán tử vật lý concatenation có hai hoặc nhiều đầu vào và một đầu ra. Ghép bản sao các hàng từ luồng đầu vào đầu tiên sang luồng đầu ra, sau đó lặp lại thao tác này cho từng luồng đầu vào bổ sung.


Câu nói đó khá gần với những gì tôi đang tìm kiếm. Tôi sẵn sàng thực hiện bước nhảy vọt từ việc được thực thi theo thứ tự đó để được trả lại theo thứ tự đó - mặc dù điều đáng thất vọng là tài liệu này ngăn cản việc xử lý song song trong trường hợp này.
Gordon Linoff

2

Cộng đồng wiki trả lời :

Tôi không biết liệu bạn có thể chứng minh rằng mọi hành vi được quan sát luôn được đảm bảo, bằng cách này hay cách khác, trừ khi bạn có thể tạo ra một ví dụ ngược lại. Trong trường hợp không có điều đó, cách để sửa thứ tự mà kết quả được trả về, tất nhiên, là thêm một ORDER BY.

Tôi không biết có "sửa chữa" hay có tồn tại nhu cầu sửa chữa hay không, nếu bạn có thể chứng minh rằng trong một số trường hợp, các truy vấn được xử lý theo một thứ tự khác.

Việc thiếu bất kỳ tài liệu chính thức, rõ ràng nào gợi ý cho tôi rằng bạn không nên phụ thuộc vào điều này. Đây chính là loại mà có người vào rắc rối với ORDER BYmột quan điểm, và GROUP BYkhông ORDER BY, 8 năm trước, khi tối ưu hóa SQL Server 2005 được phát hành.

Với tất cả các tính năng mới trong các phiên bản SQL Server mới hơn (sắp ra mắt), ngay cả khi bạn nghĩ rằng bạn có thể đảm bảo một hành vi cụ thể ngày hôm nay, tôi sẽ không hy vọng nó giữ đúng (cho đến khi được ghi lại để làm như vậy).

Ngay cả khi bạn không phụ thuộc vào hành vi này, bạn sẽ làm gì với kết quả? Dù sao, tôi sẽ không gọi một bài báo Nói chuyện đơn giản bởi một quan chức bên ngoài . Đối với tất cả chúng ta biết đây chỉ là một phỏng đoán dựa trên quan sát.

Microsoft sẽ không bao giờ xuất bản tài liệu chính thức nói rằng 'x' không được đảm bảo để làm 'y'. Đây là một trong những lý do chúng tôi vẫn, gần một thập kỷ sau, gặp khó khăn trong việc thuyết phục mọi người rằng họ không thể dựa vào việc đặt hàng được quan sát mà không có ORDER BY- không có tài liệu nào nói rằng "nó không được bảo đảm".

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.