Kullanılmayan dizinler nasıl bulunur?


11

Veri ambarı üzerinde çalışıyorum. 200M'e kadar kayıt içeren tablolarım var. Bu tabloların bazıları yaklaşık 20 + dizinleri var (neden ilk etapta oluşturulmuş bir neden veremiyorum). Bu, bu dizinleri çok acı verici hale getirme işidir ve hem performans hem de çalışma zamanında DWH içe aktarma işi üzerinde doğrudan bir etkiye sahiptir.

Her tabloda en az kullanılan dizinleri nasıl bulabilirim? (onlardan kurtulmak için)


2
Sistem görünümü sys.dm_db_index_usage_statsbu bilgileri sağlar.
Nenad Zivkovic

Yanıtlar:


10

Bu senaryoyu deneyin, Geçmişte bana yardımcı oldu:

-- Unused Index Script
-- Original Author: Pinal Dave 
SELECT TOP 25
o.name AS ObjectName
, i.name AS IndexName
, i.index_id AS IndexID
, dm_ius.user_seeks AS UserSeek
, dm_ius.user_scans AS UserScans
, dm_ius.user_lookups AS UserLookups
, dm_ius.user_updates AS UserUpdates
, p.TableRows
, 'DROP INDEX ' + QUOTENAME(i.name)
+ ' ON ' + QUOTENAME(s.name) + '.'
+ QUOTENAME(OBJECT_NAME(dm_ius.OBJECT_ID)) AS 'drop statement'
FROM sys.dm_db_index_usage_stats dm_ius
INNER JOIN sys.indexes i ON i.index_id = dm_ius.index_id 
AND dm_ius.OBJECT_ID = i.OBJECT_ID
INNER JOIN sys.objects o ON dm_ius.OBJECT_ID = o.OBJECT_ID
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
INNER JOIN (SELECT SUM(p.rows) TableRows, p.index_id, p.OBJECT_ID
FROM sys.partitions p GROUP BY p.index_id, p.OBJECT_ID) p
ON p.index_id = dm_ius.index_id AND dm_ius.OBJECT_ID = p.OBJECT_ID
WHERE OBJECTPROPERTY(dm_ius.OBJECT_ID,'IsUserTable') = 1
AND dm_ius.database_id = DB_ID()
AND i.type_desc = 'nonclustered'
AND i.is_primary_key = 0
AND i.is_unique_constraint = 0
ORDER BY (dm_ius.user_seeks + dm_ius.user_scans + dm_ius.user_lookups) ASC

http://blog.sqlauthority.com/2011/01/04/sql-server-2008-unused-index-script-download/


10

Brent Ozar Unlimited'ın (Kendra Little tarafından yazılan) ücretsiz BlitzIndex betiğinin kullanılmayan dizinleri (ve eklenecek faydalı dizinleri, diğer dizinlerin çalışmalarını çoğaltan dizinleri) izole etmenin en iyi yolu olduğunu buldum.

http://www.brentozar.com/blitzindex/

İstatistik sayımlarının son sıfırlanmasından (veya bir dizin oluşturulduğundan / yeniden oluşturulduğundan) bu yana herhangi bir dizinin kaç kez okunduğunu gösterir.

Brent Ozar'ın web yayınında iyi bir kuralın sık sık okunan bir tablo için en fazla 10 dizin, sık sık değişmeyecek statik / tarihsel / arşivlenmiş veri tabloları için 20ish olduğunu söylediğini hatırlıyorum.

Hala ithalat hızı ile ilgili sorunlar yaşıyorsanız veritabanı aktif olarak sorgulanmadığı bir zaman var (belki bu çalışma saatleri dışında). Dizini bırakmak, verileri almak ve daha sonra dizinleri yeniden uygulamak yararlı olabilir. (İstatistikler elbette sıfırlanacaktır.) Bunun nedeni, her kayıt girildikçe indekslerin güncellenmesi, sayfaların yeniden sıralanması ve zaman ve disk G / Ç almasıdır. Sonra dizinleri oluşturmak için tablonun tek bir tarama gerektirir.

Endeks türlerine ve ilgili verilere bağlı olarak bunu denemeniz zor ve hızlı bir kural yoktur. Dizinler, ihtiyaçlar / sorgular değiştikçe düzenli olarak gözden geçirilmelidir.


1
Bu senaryoyu çalıştırdım ama yorumlamak için basit bir rehber olsaydı.
IrishChieftain

0

Bunu dene:

SELECT   OBJECT_NAME(S.[OBJECT_ID]) AS [OBJECT NAME], 
             I.[NAME] AS [INDEX NAME], 
             USER_SEEKS, 
             USER_SCANS, 
             USER_LOOKUPS, 
             USER_UPDATES 
    FROM     SYS.DM_DB_INDEX_USAGE_STATS AS S 
             INNER JOIN SYS.INDEXES AS I 
               ON I.[OBJECT_ID] = S.[OBJECT_ID] 
                  AND I.INDEX_ID = S.INDEX_ID 
    WHERE    OBJECTPROPERTY(S.[OBJECT_ID],'IsUserTable') = 1 

hakimiyet


0

Raj'ın sorgusuna son vermek için son kullanılan tarih ve kodu ekledim.

SELECT   OBJECT_NAME(S.[OBJECT_ID]) AS [OBJECT NAME], 
             I.[NAME] AS [INDEX NAME], type_desc,
             coalesce(last_user_seek,last_user_scan,last_user_lookup,last_system_scan,last_system_seek,last_system_lookup) as LastUsed,
             USER_SEEKS, 
             USER_SCANS, 
             USER_LOOKUPS, 
             USER_UPDATES ,
             last_user_seek,last_user_scan,last_user_lookup,last_system_scan,last_system_seek,last_system_lookup,
             'drop index ['+I.[NAME]+'] on ['+OBJECT_NAME(S.[OBJECT_ID])+'];' as DropStatement
    FROM     SYS.DM_DB_INDEX_USAGE_STATS AS S 
             INNER JOIN SYS.INDEXES AS I 
               ON I.[OBJECT_ID] = S.[OBJECT_ID] 
                  AND I.INDEX_ID = S.INDEX_ID 
    WHERE    OBJECTPROPERTY(S.[OBJECT_ID],'IsUserTable') = 1 
    order by type_desc,coalesce(last_user_seek,last_user_scan,last_user_lookup,last_system_scan,last_system_seek,last_system_lookup) desc
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.