मैं यह समझने की कोशिश कर रहा हूं कि टेबल वेरिएबल का उपयोग करके ऑप्टिमाइज़र को इंडेक्स की तलाश में और फिर इंडेक्स स्कैन के माध्यम से बुकमार्क लुकअप से कैसे रोका जा सकता है।
तालिका पॉप्युलेट करना:
CREATE TABLE dbo.Test
(
RowKey INT NOT NULL PRIMARY KEY,
SecondColumn CHAR(1) NOT NULL DEFAULT 'x',
ForeignKey INT NOT NULL
)
INSERT dbo.Test
(
RowKey,
ForeignKey
)
SELECT TOP 1000000
ROW_NUMBER() OVER (ORDER BY (SELECT 0)),
ABS(CHECKSUM(NEWID()) % 10)
FROM sys.all_objects s1
CROSS JOIN sys.all_objects s2
CREATE INDEX ix_Test_1 ON dbo.Test (ForeignKey)
किसी एकल रिकॉर्ड के साथ तालिका चर को पॉप्युलेट करें और विदेशी कुंजी कॉलम पर खोज करके प्राथमिक कुंजी और दूसरे कॉलम को देखने का प्रयास करें:
DECLARE @Keys TABLE (RowKey INT NOT NULL)
INSERT @Keys (RowKey) VALUES (10)
SELECT
t.RowKey,
t.SecondColumn
FROM
dbo.Test t
INNER JOIN
@Keys k
ON
t.ForeignKey = k.RowKey
नीचे निष्पादन योजना है:
अब इसके बजाय एक अस्थायी तालिका का उपयोग करके एक ही क्वेरी:
CREATE TABLE #Keys (RowKey INT NOT NULL)
INSERT #Keys (RowKey) VALUES (10)
SELECT
t.RowKey,
t.SecondColumn
FROM
dbo.Test t
INNER JOIN
#Keys k
ON
t.ForeignKey = k.RowKey
यह क्वेरी प्लान एक सीक और बुकमार्क लुकअप का उपयोग करता है:
ऑप्टिमाइज़र क्यों तैयार है कि टेम्प्लेट लुकअप को टेम्प टेबल के साथ किया जाए, लेकिन टेबल वेरिएबल को नहीं?
तालिका चर का उपयोग इस उदाहरण में किया जाता है कि संग्रहीत प्रक्रिया में उपयोगकर्ता द्वारा परिभाषित तालिका प्रकार के माध्यम से आने वाले डेटा का प्रतिनिधित्व किया जाए।
मुझे एहसास है कि विदेशी महत्वपूर्ण मूल्य सैकड़ों बार होने पर सूचकांक की तलाश उचित नहीं हो सकती है। उस मामले में, एक स्कैन शायद एक बेहतर विकल्प होगा। मेरे द्वारा बनाए गए परिदृश्य के लिए, 10. के मान के साथ कोई पंक्ति नहीं थी। मुझे अभी भी लगता है कि व्यवहार दिलचस्प है और जानना चाहेंगे कि क्या इसका कोई कारण है।
जोड़ने OPTION (RECOMPILE)
से व्यवहार नहीं बदला। UDDT के पास एक प्राथमिक कुंजी है।
@@VERSION
SQL Server 2008 R2 (SP2) है - 10.50.4042.0 (X64) (7601 बनाएँ: सर्विस पैक 1) (हाइपरवाइज़र)