Bu şeyle karşılaştığımda başka bir şey araştırıyordum. İçinde bazı verilerle test tabloları oluşturuyordum ve sorgu yazmanın farklı yollarının yürütme planını nasıl etkilediğini öğrenmek için farklı sorgular çalıştırıyordum. İşte rastgele test verileri oluşturmak için kullanılan komut dosyası:
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
Şimdi, bu veriler göz önüne alındığında, aşağıdaki sorguyu çağırdı:
select *
from t
where
c2 < 1048576
or c2 is null
;
Benim için büyük sürpriz, bu sorgu için oluşturulan yürütme planı için oldu bu . (Harici bağlantı için üzgünüm, buraya sığmayacak kadar büyük).
Birisi bana tüm bu " Sürekli Taramalar " ve " Hesaplamalı Taramalar " ile ilgili neler olduğunu açıklayabilir mi? Ne oluyor?
|--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)