जब मैं इस चीज के बारे में आया तो मैं कुछ और शोध कर रहा था। मैं इसमें कुछ डेटा के साथ टेस्ट टेबल उत्पन्न कर रहा था और यह पता लगाने के लिए विभिन्न प्रश्नों को चला रहा था कि प्रश्नों को लिखने के विभिन्न तरीके निष्पादन योजना को कैसे प्रभावित करते हैं। यहां वह स्क्रिप्ट है जिसका उपयोग मैंने यादृच्छिक परीक्षण डेटा उत्पन्न करने के लिए किया था:
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
अब, इस डेटा को देखते हुए, मैंने निम्नलिखित प्रश्न को आमंत्रित किया:
select *
from t
where
c2 < 1048576
or c2 is null
;
मेरे महान आश्चर्य के लिए, इस क्वेरी के लिए जो निष्पादन योजना बनाई गई थी, वह यही थी । (बाहरी लिंक के लिए क्षमा करें, यह यहाँ फिट करने के लिए बहुत बड़ा है)।
क्या कोई मुझे समझा सकता है कि इन सभी " लगातार स्कैन " और " गणना स्केल " के साथ क्या हो रहा है? क्या हो रहा है?
|--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)