SQL Server, eksik dizin isteklerinde anahtar sütun sırasını nasıl belirler?


Yanıtlar:


44

SQL Server, belirli bir sorgu planı için eksik bir dizin önerisi oluşturduğunda, olası anahtar sütunları 2 gruba ayırır. İlk set, bir EQUALITY yüklemesinin parçası olan önerilen tüm sütunları içerir. İkinci set, bir INEQUALITY yükleminin parçası olan önerilen tüm sütunları içerir.

Her bir kümede, sütunlar, tablo tanımına bağlı olarak, sütunların sıralı konumuna göre sıralanır.

(Bunu kanıtlamak için Stack Overflow veritabanına karşı bir repro betiği hazırladığı için Brent Ozar'a teşekkür ederiz!)

1. Aynı 3 tablo oluşturun , ancak sütunlarını farklı sıraya koyun. (Buradaki neden, eksik dizin önerisinde sütun sırasını etkilemediğini göstermek için çeşitli sütun adları ve veri türleri kullanmaktır.)

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. Tabloları aynı verilerle doldurun. Gerçek dünya veri dağıtımıyla Kullanıcılar tablosundan 100.000 satır alın.

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. Dizin gerektiren bir sorgu yazın. 3 eşitlik filtresiyle başlayın, her 3 alanda da kesin bir değere bakın. 3 sorgunun hepsinin aynı sırada aynı alanlara sahip olduğunu unutmayın:

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

Her üç tablo da aynı veriye sahiptir ve sorgular aynıdır. Tek fark saha emridir - ve eksik endeks taleplerimizdeki de fark bu:

3 eşitlik alanına sahip yürütme planları

Uygulama planlarında, eksik indeks isteğindeki sütun sırası, tablodaki sütun sırası ile tam olarak eşleşiyor. Örneğin, dbo.NumberLetterDate'de sayı sütunu ilk sıradadır, bu nedenle eksik dizin isteğinde de ilk sırada bulunur:

  • Dbo.NumberLetterDate'de, eksik dizin fINT (sayı), fLetter (nvarchar), fDate, tablodaki alanların aynı sırasına gelir
  • Dbo.LetterDateNumber'da, dizin sırası fNVARCHAR, fDATE, fINT olarak değişir
  • Dbo.DateNumberLetter'da, dizin sırası fDATE, fINT, fNVARCHAR olarak değişir

Bunun gibi tek bir tablo için, dizin alanı sırası, seçiciliğe, veri türüne veya sorgudaki konuma bağlı görünmüyor. (Bunu daha karmaşık sorgular ve katılımlarla kanıtlamak için diğer insanlara bırakıyorum.)

4. Bir eşitsizlik filtresinde karıştırın. INT alanında, örneğin, filtre olarak <> 100 koyun:

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

Yürütme planlarında eşitlik alanları önce gider, sonra eşitsizlik alanları - yani burada fINT, eksik olan 3 endeks talebinde en son ortaya çıkar çünkü bu bir eşitsizlik araştırmasıdır:

2 eşitlik ve 1 eşitsizlik araştırmasına sahip yürütme planları

5. 3 eşitsizlik filtresi kullanın. Tüm alanlar için aynı aramayı kullanın (<>):

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

Eşitlik araması olmadığından, 3 alanın tümü de eksik dizin önerisinde aynı öncelik sırasına sahiptir ve şimdi tamamen alan sıralamasına göre sıralamaya döndük:

3 eşitsizlik araştırması içeren yürütme planları

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.