Hằng số quét từng tạo ra một hàng trong bộ nhớ duy nhất không có cột. Số vô hướng tính toán trên cùng xuất ra một hàng đơn có 3 cột
Expr1005 Expr1006 Expr1004
----------- ----------- -----------
NULL NULL 60
Tính toán vô hướng dưới cùng xuất ra một hàng đơn có 3 cột
Expr1008 Expr1009 Expr1007
----------- ----------- -----------
NULL 1048576 10
Toán tử ghép nối Liên kết 2 hàng này lại với nhau và xuất ra 3 cột nhưng giờ chúng được đổi tên
Expr1010 Expr1011 Expr1012
----------- ----------- -----------
NULL NULL 60
NULL 1048576 10
Các Expr1012
cột là một tập hợp của những lá cờ sử dụng trong nội bộ để xác định một số tìm kiếm bất động sản cho Công cụ lưu trữ .
Tính toán vô hướng tiếp theo dọc theo đầu ra 2 hàng
Expr1010 Expr1011 Expr1012 Expr1013 Expr1014 Expr1015
----------- ----------- ----------- ----------- ----------- -----------
NULL NULL 60 True 4 16
NULL 1048576 10 False 0 0
Ba cột cuối cùng được định nghĩa như sau và chỉ được sử dụng để sắp xếp các mục đích trước khi trình bày cho Toán tử Khoảng thời gian Hợp nhất
[Expr1013] = Scalar Operator(((4)&[Expr1012]) = (4) AND NULL = [Expr1010]),
[Expr1014] = Scalar Operator((4)&[Expr1012]),
[Expr1015] = Scalar Operator((16)&[Expr1012])
Expr1014
và Expr1015
chỉ kiểm tra xem một số bit nhất định có trong cờ không.
Expr1013
xuất hiện để trả về một cột boolean đúng nếu cả hai bit 4
được bật và Expr1010
là NULL
.
Từ việc thử các toán tử so sánh khác trong truy vấn, tôi nhận được các kết quả này
+----------+----------+----------+-------------+----+----+---+---+---+---+
| Operator | Expr1010 | Expr1011 | Flags (Dec) | Flags (Bin) |
| | | | | 32 | 16 | 8 | 4 | 2 | 1 |
+----------+----------+----------+-------------+----+----+---+---+---+---+
| > | 1048576 | NULL | 6 | 0 | 0 | 0 | 1 | 1 | 0 |
| >= | 1048576 | NULL | 22 | 0 | 1 | 0 | 1 | 1 | 0 |
| <= | NULL | 1048576 | 42 | 1 | 0 | 1 | 0 | 1 | 0 |
| < | NULL | 1048576 | 10 | 0 | 0 | 1 | 0 | 1 | 0 |
| = | 1048576 | 1048576 | 62 | 1 | 1 | 1 | 1 | 1 | 0 |
| IS NULL | NULL | NULL | 60 | 1 | 1 | 1 | 1 | 0 | 0 |
+----------+----------+----------+-------------+----+----+---+---+---+---+
Từ đó tôi suy ra rằng Bit 4 có nghĩa là "Đã bắt đầu phạm vi" (trái ngược với việc không bị ràng buộc) và Bit 16 có nghĩa là bắt đầu phạm vi được bao gồm.
Tập kết quả 6 cột này được phát ra từ SORT
toán tử được sắp xếp theo
Expr1013 DESC, Expr1014 ASC, Expr1010 ASC, Expr1015 DESC
. Giả sử True
được đại diện bởi 1
và False
bởi 0
các kết quả được đại diện trước đó đã theo thứ tự đó.
Dựa trên các giả định trước đây của tôi, hiệu ứng ròng của loại này là trình bày các phạm vi cho khoảng thời gian hợp nhất theo thứ tự sau
ORDER BY
HasStartOfRangeAndItIsNullFirst,
HasUnboundedStartOfRangeFirst,
StartOfRange,
StartOfRangeIsInclusiveFirst
Toán tử khoảng thời gian hợp nhất xuất ra 2 hàng
Expr1010 Expr1011 Expr1012
----------- ----------- -----------
NULL NULL 60
NULL 1048576 10
Đối với mỗi hàng phát ra một phạm vi tìm kiếm được thực hiện
Seek Keys[1]: Start:[dbo].[t].c2 > Scalar Operator([Expr1010]),
End: [dbo].[t].c2 < Scalar Operator([Expr1011])
Vì vậy, nó sẽ xuất hiện như thể hai tìm kiếm được thực hiện. Một rõ ràng > NULL AND < NULL
và một > NULL AND < 1048576
. Tuy nhiên, các cờ được truyền vào xuất hiện để sửa đổi điều này thành IS NULL
và < 1048576
tương ứng. Hy vọng @sqlkiwi có thể làm rõ điều này và sửa chữa mọi điểm không chính xác!
Nếu bạn thay đổi truy vấn một chút thành
select *
from t
where
c2 > 1048576
or c2 = 0
;
Sau đó, kế hoạch trông đơn giản hơn nhiều với một tìm kiếm chỉ mục với nhiều biến vị ngữ tìm kiếm.
Kế hoạch cho thấy Seek Keys
Start: c2 >= 0, End: c2 <= 0,
Start: c2 > 1048576
Giải thích cho lý do tại sao kế hoạch đơn giản hơn này không thể được sử dụng cho trường hợp trong OP được SQLKiwi đưa ra trong các nhận xét cho bài đăng trên blog được liên kết trước đó .
Một chỉ mục tìm kiếm với nhiều biến vị ngữ không thể trộn lẫn các loại vị từ so sánh khác nhau (nghĩa là Is
và Eq
trong trường hợp trong OP). Đây chỉ là một giới hạn hiện tại của sản phẩm (và có lẽ là lý do tại sao kiểm tra tính bằng trong truy vấn cuối cùng c2 = 0
được thực hiện bằng cách sử dụng >=
và <=
thay vì chỉ là sự bình đẳng đơn giản mà bạn tìm kiếm cho truy vấn c2 = 0 OR c2 = 1048576
.