Tôi muốn tạo một bảng với một NOT NULL
cột bool.
Tôi sử dụng TINYINT
với sự CHECK
rà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 >= 2
tô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 NULL
hoặ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 TINYINT
với CHECK
ràng buộc. Loại người dùng xác định dựa trên TINYINT
ràng buộc RULE
và 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.