Sorguların oldukça yavaş olduğu bir SQL Server veritabanım var ve kilitleme ve engelleme çok.
Eksik dizin DMV'lerine ve sorgu planlarına baktığımda herhangi bir öneri yok.
Neden?
Sorguların oldukça yavaş olduğu bir SQL Server veritabanım var ve kilitleme ve engelleme çok.
Eksik dizin DMV'lerine ve sorgu planlarına baktığımda herhangi bir öneri yok.
Neden?
Yanıtlar:
Nedenlerin birkaçına daha ayrıntılı olarak bakacağız ve ayrıca özelliğin genel kısıtlamalarından bazılarından bahsedeceğiz.
İlk olarak, Eksik Dizinler Özelliğinin Sınırlamaları :
- Bir dizinde kullanılacak sütunların sırasını belirtmez.
Bu soru-cevap bölümünde belirtildiği gibi: SQL Server eksik dizin isteklerinde anahtar sütun sırasını nasıl belirler? , dizin tanımındaki sütunların sırası Eşitlik ve Eşitsizlik yüklemi tarafından belirlenir ve daha sonra tablodaki sütun sıralı konumu tarafından belirlenir.
Seçicilikte tahmin yoktur ve daha iyi bir sipariş olabilir. Bunu anlamak sizin göreviniz.
Özel Endeksler
Eksik dizin istekleri de 'özel' dizinleri kapsamaz, örneğin:
Eksik Dizin anahtar sütunları, aşağıdakiler gibi sonuçları filtrelemek için kullanılan sütunlardan oluşturulur:
Eksik Dizin Dahil edilen sütunlar, aşağıdakiler gibi sorgu tarafından istenen sütunlardan oluşturulur:
Sıklıkla sipariş verdiğiniz veya gruplandırdığınız sütunlar, anahtar sütunlar olarak yararlı olabilir. Bu, Sınırlamalardan birine kadar gider:
- Bir dizin oluşturma yapılandırmasında ince ayar yapılması amaçlanmamıştır.
Örneğin, LastAccessDate'e bir dizin eklemek Sıralama (ve diske dökülme) ihtiyacını engellemesine rağmen, bu sorgu eksik bir dizin isteği kaydetmez.
SELECT TOP (1000) u.DisplayName
FROM dbo.Users AS u
ORDER BY u.LastAccessDate DESC;
Bu gruplama Konum üzerinde de sorgulanmaz.
SELECT TOP (20000) u.Location
FROM dbo.Users AS u
GROUP BY u.Location
Evet, ama hiç yoktan iyidir. Eksik dizin isteklerini ağlayan bir bebek gibi düşünün. Bir sorun olduğunu biliyorsunuz, ancak bu sorunun ne olduğunu anlamak bir yetişkin olarak size kalmış.
Sakin ol, bucko. Biz oraya varıyoruz.
TF 2330'u etkinleştirirseniz , eksik dizin istekleri kaydedilmez. Bunu etkinleştirip etkinleştirmediğinizi öğrenmek için şunu çalıştırın:
DBCC TRACESTATUS;
Dizinlerin yeniden oluşturulması eksik dizin isteklerini temizler. Bu yüzden gitmeden önce Hi-Ho-Silver-Away her dizini yeniden oluştururken, ikinci bir parçalanma iota gizlice girer, bunu her yaptığınızda temizlediğiniz bilgileri düşünün.
Ayrıca , Dizinlerinizi Birleştirmenin Neden Yardımcı Olmadığını da düşünmek isteyebilirsiniz . Columnstore kullanmadığınız sürece .
Bir dizin eklenmesi, kaldırılması veya devre dışı bırakılması, o tablo için eksik dizin isteklerinin tümünü temizler. Aynı tabloda birkaç dizin değişikliği üzerinde çalışıyorsanız, herhangi bir işlem yapmadan önce hepsini komut dosyası yazdığınızdan emin olun.
Bir plan yeterince basitse ve dizin erişim seçimi yeterince açıksa ve maliyet yeterince düşükse, önemsiz bir plan alırsınız.
Bu, optimize edicinin vereceği maliyete dayalı kararların olmadığı anlamına gelir.
Via Paul Beyaz :
Hangi tür sorguların Önemsiz Plan'dan faydalanabileceği ayrıntıları sık sık değişir, ancak birleştirme, alt sorgular ve eşitsizlik tahminleri genellikle bu optimizasyonu önler.
Bir plan önemsiz olduğunda, ek optimizasyon aşamaları araştırılmaz ve eksik dizinler istenmez .
Bu sorgular ile planları arasındaki farkı görün :
SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2;
SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2
AND 1 = (SELECT 1);
İlk plan önemsizdir ve hiçbir talep gösterilmez. Hata sorgularının eksik dizinlerin sorgu planlarında görünmesini engellediği durumlar olabilir; Bununla birlikte, genellikle eksik endeks DMV'lerine daha güvenilir bir şekilde kaydedilirler.
Optimize edicinin bir dizinde bile bir dizini verimli bir şekilde kullanamayacağını tahmin ederek bunların günlüğe kaydedilmesini engelleyebilir.
Genellikle SARGable olmayan şeyler:
SELECT *
FROM dbo.Users AS u
WHERE ISNULL(u.Age, 1000) > 1000;
SELECT *
FROM dbo.Users AS u
WHERE DATEDIFF(DAY, u.CreationDate, u.LastAccessDate) > 5000
SELECT *
FROM dbo.Users AS u
WHERE u.UpVotes + u.DownVotes > 10000000
DECLARE @ThisWillHappenWithStoredProcedureParametersToo NVARCHAR(40) = N'Eggs McLaren'
SELECT *
FROM dbo.Users AS u
WHERE u.DisplayName LIKE @ThisWillHappenWithStoredProcedureParametersToo
OR @ThisWillHappenWithStoredProcedureParametersToo IS NULL;
Bu sorguların hiçbiri eksik dizin isteklerini kaydetmez. Bunlar hakkında daha fazla bilgi için aşağıdaki bağlantılara göz atın:
Bu dizini al:
CREATE INDEX ix_whatever ON dbo.Posts(CreationDate, Score) INCLUDE(OwnerUserId);
Bu sorgu için iyi görünüyor:
SELECT p.OwnerUserId, p.Score
FROM dbo.Posts AS p
WHERE p.CreationDate >= '20070101'
AND p.CreationDate < '20181231'
AND p.Score >= 25000
AND 1 = (SELECT 1)
ORDER BY p.Score DESC;
Plan basit bir arayış ...
Ancak, önde gelen anahtar sütun daha az seçici yüklem için olduğu için, sonuçta olması gerekenden daha fazla iş yapıyoruz:
Tablo 'Yayınlar'. Tarama sayısı 13, mantıksal okuma 136890
Dizin anahtarı sütun sırasını değiştirirsek, çok daha az iş yaparız:
CREATE INDEX ix_whatever ON dbo.Posts(Score, CreationDate) INCLUDE(OwnerUserId);
Ve önemli ölçüde daha az okuma:
Tablo 'Yayınlar'. Tarama sayısı 1, mantıksal okuma 5
Bazı durumlarda, SQL Server anında bir dizin biriktirme yoluyla bir dizin oluşturmayı seçecektir. Bir dizin biriktiricisi varsa, eksik bir dizin isteği olmaz. Elbette dizini kendiniz eklemek iyi bir fikir olabilir, ancak bunu çözmenize yardımcı olan SQL Server'a güvenmeyin.