SQL सर्वर अनुपलब्ध अनुक्रमणिका अनुरोधों में प्रमुख स्तंभ क्रम कैसे निर्धारित करता है?


32

SQL सर्वर क्वेरी योजना के लिए अपनी अनुपलब्ध अनुक्रमणिका अनुशंसाओं में प्रमुख स्तंभों के क्रम को कैसे निर्धारित करता है?

जवाबों:


44

जब SQL सर्वर किसी विशेष क्वेरी प्लान के लिए एक अनुपलब्ध इंडेक्स अनुशंसा बनाता है, तो यह संभावित कुंजी कॉलम को 2 समूहों में अलग करता है। पहले सेट में सभी अनुशंसित कॉलम शामिल हैं जो एक एक्वैलिटी प्रेडिकेट का हिस्सा हैं। दूसरे सेट में सभी अनुशंसित कॉलम शामिल हैं जो एक INEQUALITY की भविष्यवाणी का हिस्सा हैं।

प्रत्येक सेट के भीतर, स्तंभों की क्रमिक स्थिति के आधार पर तालिका की परिभाषा के आधार पर कॉलम का आदेश दिया जाता है।

(इस बात को साबित करने के लिए स्टैक ओवरफ्लो डेटाबेस के खिलाफ रेप्रो स्क्रिप्ट बनाने के लिए ब्रेंट ओज़र का बहुत धन्यवाद!)

1. 3 समान टेबल बनाएं , लेकिन उनके कॉलम अलग-अलग क्रम में रखें। (इसका कारण यह है कि स्तंभ के विभिन्न नामों और डेटाटिप्स का उपयोग यह दिखाने के लिए है कि अनुपलब्ध अनुक्रमणिका अनुशंसा में स्तंभ क्रम को प्रभावित नहीं करता है।)

CREATE TABLE dbo.NumberLetterDate (ID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED, 
fINT INT, fNVARCHAR NVARCHAR(40), fDATE DATETIME, AboutMe NVARCHAR(MAX));
GO
CREATE TABLE dbo.LetterDateNumber (ID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED, 
fNVARCHAR NVARCHAR(40), fDATE DATETIME, fINT INT, AboutMe NVARCHAR(MAX));
GO
CREATE TABLE dbo.DateNumberLetter (ID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
fDATE DATETIME, fINT INT, fNVARCHAR NVARCHAR(40), AboutMe NVARCHAR(MAX));
GO

2. समान डेटा वाली तालिकाओं को आबाद करें। वास्तविक-विश्व डेटा वितरण के साथ उपयोगकर्ता तालिका से 100,000 पंक्तियाँ प्राप्त करें।

INSERT INTO dbo.NumberLetterDate(fINT, fNVARCHAR, fDATE, AboutMe)
SELECT TOP 100000 Age, DisplayName, LastAccessDate, AboutMe
  FROM dbo.Users WITH (NOLOCK)
  ORDER BY Id;
GO
INSERT INTO dbo.LetterDateNumber(fINT, fNVARCHAR, fDATE, AboutMe)
SELECT TOP 100000 Age, DisplayName, LastAccessDate, AboutMe
  FROM dbo.Users WITH (NOLOCK)
  ORDER BY Id;
GO
INSERT INTO dbo.DateNumberLetter(fINT, fNVARCHAR, fDATE, AboutMe)
SELECT TOP 100000 Age, DisplayName, LastAccessDate, AboutMe
  FROM dbo.Users WITH (NOLOCK)
  ORDER BY Id;
GO

3. एक प्रश्न लिखें, जिसमें सूचकांक की आवश्यकता हो। सभी 3 क्षेत्रों में सटीक मूल्य के लिए फ़िल्टरिंग, 3 समानता फ़िल्टर के साथ शुरू करें। ध्यान दें कि सभी 3 प्रश्नों के समान क्रम में एक ही फ़ील्ड हैं:

SELECT ID
  FROM dbo.NumberLetterDate
  WHERE fINT = 100
  AND fNVARCHAR = 'Brent Ozar'
  AND fDATE = '2018/01/01'
  AND 1 = (SELECT 1);

SELECT ID
  FROM dbo.LetterDateNumber
  WHERE fINT = 100
  AND fNVARCHAR = 'Brent Ozar'
  AND fDATE = '2018/01/01'
  AND 1 = (SELECT 1);

SELECT ID
  FROM dbo.DateNumberLetter
  WHERE fINT = 100
  AND fNVARCHAR = 'Brent Ozar'
  AND fDATE = '2018/01/01'
  AND 1 = (SELECT 1);
GO

सभी तीन तालिकाओं में समान डेटा है, और क्वेरी समान हैं। एकमात्र अंतर फ़ील्ड ऑर्डर है - और हमारे लापता सूचकांक अनुरोधों में भी यही अंतर है:

निष्पादन की योजना 3 समानता क्षेत्रों के साथ है

निष्पादन योजनाओं में, अनुपलब्ध अनुक्रमणिका अनुरोध में स्तंभ क्रम तालिका में स्तंभ क्रम से बिल्कुल मेल खाता है। उदाहरण के लिए, dbo.NumberLetterDate में, संख्या स्तंभ पहले है, इसलिए यह अनुपलब्ध अनुक्रमणिका अनुरोध में भी सबसे पहले है:

  • Dbo.NumberLetterDate पर, लापता सूचकांक fINT (संख्या), fLetter (nvarchar), fDate पर है, तालिका में फ़ील्ड का समान क्रम
  • Dbo.LetterDateNumber पर, सूचकांक क्रम fNVARCHAR, fDATE, fINT पर स्विच हो जाता है
  • Dbo.DateNumberLetter पर, सूचकांक आदेश fDATE, fINT, fNVARCHAR पर स्विच करता है

इस तरह एकल-तालिका संचालन के लिए, अनुक्रमणिका फ़ील्ड क्रम चयनात्मकता, डेटाटाइप या क्वेरी में स्थिति पर निर्भर नहीं होता है। (अधिक जटिल प्रश्नों और जुड़ावों के साथ इसे साबित करने के लिए मैं इसे अन्य लोगों पर छोड़ता हूं।)

4. असमानता फिल्टर में मिलाएं। INT फ़ील्ड पर, उदाहरण के लिए, फ़िल्टर के रूप में <> 100 में डालें:

SELECT ID
  FROM dbo.NumberLetterDate
  WHERE fINT <> 100
  AND fNVARCHAR = 'Brent Ozar'
  AND fDATE = '2018/01/01'
  AND 1 = (SELECT 1);

SELECT ID
  FROM dbo.LetterDateNumber
  WHERE fINT <> 100
  AND fNVARCHAR = 'Brent Ozar'
  AND fDATE = '2018/01/01'
  AND 1 = (SELECT 1);

SELECT ID
  FROM dbo.DateNumberLetter
  WHERE fINT <> 100
  AND fNVARCHAR = 'Brent Ozar'
  AND fDATE = '2018/01/01'
  AND 1 = (SELECT 1);
GO

निष्पादन योजनाओं में, समानता के क्षेत्र पहले जाते हैं, फिर असमानता के क्षेत्र - इसलिए, सभी 3 लापता सूचकांक अनुरोधों में अंतिम पता चलता है क्योंकि यह एक असमानता खोज है:

निष्पादन की योजना 2 समानता और 1 असमानता खोज के साथ है

5. 3 असमानता फिल्टर का उपयोग करें। सभी फ़ील्ड के लिए समान खोज का उपयोग करें (<>):

SELECT ID
  FROM dbo.NumberLetterDate
  WHERE fINT <> 100
  AND fNVARCHAR <> 'Brent Ozar'
  AND fDATE <> '2018/01/01'
  AND 1 = (SELECT 1);

SELECT ID
  FROM dbo.LetterDateNumber
  WHERE fINT <> 100
  AND fNVARCHAR <> 'Brent Ozar'
  AND fDATE <> '2018/01/01'
  AND 1 = (SELECT 1);

SELECT ID
  FROM dbo.DateNumberLetter
  WHERE fINT <> 100
  AND fNVARCHAR <> 'Brent Ozar'
  AND fDATE <> '2018/01/01'
  AND 1 = (SELECT 1);
GO

चूँकि कोई समानता खोज नहीं है, सभी 3 फ़ील्ड्स की अनुपलब्ध अनुक्रमणिका अनुशंसा में समान प्राथमिकता क्रम है, और अब हम फ़ील्ड क्रम से विशुद्ध रूप से छँटाई करने के लिए वापस आ गए हैं:

3 असमानता खोजों के साथ निष्पादन की योजना

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.