यह थोड़ा व्यापक है लेकिन मुझे लगता है कि मैं सच्चे प्रश्न को समझता हूं और उसी के अनुसार उत्तर दूंगा। बस टेबल बनाम इंडेक्स स्पूल के बारे में बात करने जा रहा है। मुझे नहीं लगता कि टेबल और इंडेक्स स्पूल के बीच कोई विकल्प होने के नाते यह देखना काफी सही है। जैसा कि आप जानते हैं, इंडेक्स स्पूल, टेबल स्पूल या इंडेक्स स्पूल और टेबल स्पूल दोनों को प्राप्त करने के लिए सिंगल सबट्री में संभव है। मेरा मानना है कि आमतौर पर यह कहना सही है कि आपको निम्नलिखित परिस्थितियों में एक सूचकांक स्पूल मिलता है:
- क्वेरी ऑप्टिमाइज़र के पास एक जुड़ने को एक आवेदन में बदलने का एक कारण है
- क्वेरी ऑप्टिमाइज़र वास्तव में लागू करने के लिए परिवर्तन करता है
- क्वेरी ऑप्टिमाइज़र इंडेक्स स्पूल जोड़ने के लिए नियम का उपयोग करता है (कम से कम इंडेक्स स्पूल को उपयोग करने के लिए सुरक्षित होना चाहिए)
- सूचकांक स्पूल के साथ योजना का चयन किया जाता है
आप इनमें से अधिकांश को साधारण डेमो के साथ देख सकते हैं। ढेर की एक जोड़ी बनाकर शुरू करें:
DROP TABLE IF EXISTS dbo.X_10000_VARCHAR_901;
CREATE TABLE dbo.X_10000_VARCHAR_901 (ID VARCHAR(901) NOT NULL);
INSERT INTO dbo.X_10000_VARCHAR_901 WITH (TABLOCK)
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
DROP TABLE IF EXISTS dbo.X_10000_VARCHAR_800;
CREATE TABLE dbo.X_10000_VARCHAR_800 (ID VARCHAR(800) NOT NULL);
INSERT INTO dbo.X_10000_VARCHAR_800 WITH (TABLOCK)
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
पहली क्वेरी के लिए, इस पर तलाश करने के लिए कुछ नहीं है:
SELECT *
FROM dbo.X_10000_VARCHAR_901 a
CROSS JOIN dbo.X_10000_VARCHAR_901 b
OPTION (MAXDOP 1);
इसलिए ऑप्टिमाइज़र के लिए कोई कारण नहीं है कि वह एक अप्लाई में बदल जाए। आप लागत कारणों के कारण एक टेबल स्पूल के साथ समाप्त होते हैं। तो यह क्वेरी पहले परीक्षण में विफल रहती है।
अगली क्वेरी के लिए, यह आशा करना उचित है कि ऑप्टिमाइज़र के पास एक आवेदन पर विचार करने का एक कारण है:
SELECT *
FROM dbo.X_10000_VARCHAR_901 a
INNER JOIN dbo.X_10000_VARCHAR_901 b ON a.ID = b.ID
OPTION (LOOP JOIN, MAXDOP 1);
लेकिन इसका मतलब यह नहीं है:
यह क्वेरी दूसरा परीक्षण विफल करती है। एक पूरी व्याख्या यहाँ है । सबसे अधिक प्रासंगिक भाग का हवाला देते हुए:
आशावादी एक आवेदन को सक्षम करने के लिए मक्खी पर एक सूचकांक बनाने पर विचार नहीं करता है; बल्कि घटनाओं का क्रम आमतौर पर उल्टा होता है: एक अच्छा सूचकांक मौजूद होने के कारण इसे लागू करने के लिए रूपांतरित करें।
मैं ऑप्टिमाइज़र को एक आवेदन पर विचार करने के लिए प्रोत्साहित करने के लिए क्वेरी को फिर से लिख सकता हूँ:
SELECT *
FROM dbo.X_10000_VARCHAR_901 a
INNER JOIN dbo.X_10000_VARCHAR_901 b ON a.ID >= b.ID AND a.ID <= b.ID
OPTION (MAXDOP 1);
लेकिन अभी भी कोई सूचकांक स्पूल नहीं है:
यह क्वेरी तीसरे परीक्षण में विफल रहती है। SQL सर्वर 2014 में 900 बाइट्स की एक इंडेक्स की लंबाई सीमा थी। यह SQL Server 2016 में विस्तारित किया गया था, लेकिन केवल गैर-अनुक्रमित अनुक्रमित के लिए। स्पूल के लिए इंडेक्स एक क्लस्टर इंडेक्स होता है इसलिए यह सीमा 900 बाइट्स पर रहती है । किसी भी मामले में, सूचकांक स्पूल नियम लागू नहीं किया जा सकता है क्योंकि यह क्वेरी निष्पादन के दौरान त्रुटि का कारण बन सकता है।
डेटा प्रकार की लंबाई को 800 तक कम करना अंत में एक सूचकांक स्पूल के साथ एक योजना प्रदान करता है:
सूचकांक स्पूल योजना, आश्चर्यजनक रूप से नहीं, बिना स्पूल वाली योजना की तुलना में काफी सस्ती है: 89.7603 यूनिट बनाम 598.832 यूनिट। आप अविभाजित QUERYRULEOFF BuildSpool
क्वेरी संकेत के साथ अंतर देख सकते हैं :
यह पूर्ण उत्तर नहीं है, लेकिन उम्मीद है कि यह कुछ ऐसा है जिसे आप खोज रहे थे।