Saya sedang meneliti sesuatu yang lain ketika saya menemukan hal ini. Saya menghasilkan tabel uji dengan beberapa data di dalamnya dan menjalankan kueri yang berbeda untuk mengetahui bagaimana cara berbeda untuk menulis kueri mempengaruhi rencana eksekusi. Berikut ini skrip yang saya gunakan untuk menghasilkan data uji acak:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID('t') AND type in (N'U'))
DROP TABLE t
GO
CREATE TABLE t
(
c1 int IDENTITY(1,1) NOT NULL
,c2 int NULL
)
GO
insert into t
select top 1000000 a from
(select t1.number*2048 + t2.number a, newid() b
from [master]..spt_values t1
cross join [master]..spt_values t2
where t1.[type] = 'P' and t2.[type] = 'P') a
order by b
GO
update t set c2 = null
where c2 < 2048 * 2048 / 10
GO
CREATE CLUSTERED INDEX pk ON [t] (c1)
GO
CREATE NONCLUSTERED INDEX i ON t (c2)
GO
Sekarang, mengingat data ini, saya meminta pertanyaan berikut:
select *
from t
where
c2 < 1048576
or c2 is null
;
Yang sangat mengejutkan saya, rencana eksekusi yang dihasilkan untuk permintaan ini, adalah ini . (Maaf untuk tautan eksternal, terlalu besar untuk muat di sini).
Adakah yang bisa menjelaskan kepada saya apa yang terjadi dengan semua " Pemindaian Konstan " dan " Kalkulator Komputasi " ini? Apa yang terjadi?
|--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1010], [Expr1011], [Expr1012]))
|--Merge Interval
| |--Sort(TOP 2, ORDER BY:([Expr1013] DESC, [Expr1014] ASC, [Expr1010] ASC, [Expr1015] DESC))
| |--Compute Scalar(DEFINE:([Expr1013]=((4)&[Expr1012]) = (4) AND NULL = [Expr1010], [Expr1014]=(4)&[Expr1012], [Expr1015]=(16)&[Expr1012]))
| |--Concatenation
| |--Compute Scalar(DEFINE:([Expr1005]=NULL, [Expr1006]=NULL, [Expr1004]=(60)))
| | |--Constant Scan
| |--Compute Scalar(DEFINE:([Expr1008]=NULL, [Expr1009]=(1048576), [Expr1007]=(10)))
| |--Constant Scan
|--Index Seek(OBJECT:([t].[i]), SEEK:([t].[c2] > [Expr1010] AND [t].[c2] < [Expr1011]) ORDERED FORWARD)