Tôi muốn tạo một bảng với một NOT NULLcột bool.
Tôi sử dụng TINYINTvới sự CHECKràng buộc BETWEEN 0 and 1. Các ràng buộc là mới và do đó đáng tin cậy
Bây giờ tôi mong rằng trình tối ưu hóa SQL bây giờ biết rằng cột này chỉ có thể là 0 và 1 vì vậy khi tôi viết truy vấn, col >= 2tôi sẽ thấy Constant Scan trong kế hoạch thực hiện thực tế (như khi tôi sẽ kiểm tra NULLhoặcSELECT TOP (0)
Nhưng đây không phải là trường hợp, nó phù hợp với Quét bảng. Tôi cũng cần phải có chỉ mục trên cột này?
Trong thử nghiệm của tôi dưới đây tôi sử dụng TINYINTvới CHECKràng buộc. Loại người dùng xác định dựa trên TINYINTràng buộc RULEvà cũ tốt BIT.
GO
CREATE TYPE dbo.myBool
FROM [INT] NOT NULL
GO
CREATE RULE dbo.R_Bool AS @value BETWEEN 0 AND 1
go
EXEC sys.sp_bindrule @rulename = N'R_Bool'
, @objname = N'myBool'
GO
DROP TABLE IF EXISTS dbo.RuleTest
CREATE TABLE dbo.RuleTest
(
Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED
, oldSchoolBool TINYINT NOT NULL CHECK (oldSchoolBool BETWEEN 0 AND 1)
, customBool dbo.myBool NOT NULL
, myBit BIT NOT NULL
)
;WITH tally (n)
AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM (VALUES (0), (0), (0), (0), (0), (0), (0), (0), (0), (0)) AS a(n)
CROSS JOIN (VALUES (0), (0), (0), (0), (0), (0), (0), (0), (0), (0)) AS b(n)
CROSS JOIN (VALUES (0), (0), (0), (0), (0), (0), (0), (0), (0), (0)) AS c(n)
)
INSERT INTO dbo.RuleTest
(oldSchoolBool, customBool, myBit)
SELECT
ABS(CHECKSUM(NewId())) % 2
,ABS(CHECKSUM(NewId())) % 2
,ABS(CHECKSUM(NewId())) % 2
FROM tally t
SET STATISTICS IO ON;
SELECT * FROM dbo.RuleTest rt
WHERE rt.oldSchoolBool IS NULL
SELECT * FROM dbo.RuleTest rt
WHERE rt.oldSchoolBool >=2
go
SELECT * FROM dbo.RuleTest rt
WHERE rt.customBool >=2
go
SELECT * FROM dbo.RuleTest rt
WHERE rt.myBit >= 2
SET STATISTICS IO OFF;
Tôi thấy một Quét liên tục cho kiểm tra NULL và 3 lần quét bảng cho phần còn lại.
WHERE myBit >= 2điều kiện khi bạn biết các giá trị không bao giờ có thể lớn hơn 1.
