Làm thế nào để tìm các chỉ mục không sử dụng?


11

Tôi đang làm việc trên một kho dữ liệu. Tôi có các bảng với hồ sơ lên ​​tới 200M. Một số bảng này có khoảng hơn 20 chỉ mục (Tôi không thể cung cấp lý do tại sao chúng được tạo ở vị trí đầu tiên). Điều này làm cho công việc duy trì các chỉ số này quá đau đớn và có tác động trực tiếp đến công việc nhập khẩu DWH trong cả hiệu suất và thời gian chạy.

Làm thế nào tôi có thể tìm thấy các chỉ mục ít được sử dụng nhất trên mỗi bảng? (để thoát khỏi chúng)


2
Chế độ xem hệ thống sys.dm_db_index_usage_statscung cấp thông tin đó.
Nenad Zivkovic

Câu trả lời:


10

Hãy thử kịch bản này, Nó đã giúp tôi trong quá khứ:

-- 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-unuse-index-script-doad/


10

Tôi đã thấy rằng tập lệnh Blitz Index miễn phí của Brent Ozar Unlimited (được viết bởi Kendra Little) là cách tốt nhất để cô lập các chỉ mục không được sử dụng (cũng như các chỉ mục có lợi để thêm vào, các chỉ mục đang sao chép công việc của các chỉ mục khác, v.v.)

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

Nó sẽ cho bạn biết số lần bất kỳ chỉ mục nào được đọc kể từ lần cuối cùng số lượng thống kê được đặt lại (hoặc một chỉ mục được tạo / tạo lại).

Tôi dường như nhớ Brent Ozar nói trong webcast rằng một quy tắc tốt là không quá 10 chỉ mục cho một bảng được đọc thường xuyên, 20ish cho các bảng là dữ liệu tĩnh / lịch sử / lưu trữ sẽ không thay đổi thường xuyên.

Nếu bạn vẫn gặp vấn đề với tốc độ nhập thì đã có lúc cơ sở dữ liệu không được truy vấn tích cực (có lẽ đây là giờ làm việc). Có thể có ích khi bỏ chỉ mục, nhập dữ liệu và sau đó áp dụng lại các chỉ mục. (Tất nhiên, số liệu thống kê sẽ được đặt lại.) Lý do cho điều này là (các) chỉ mục sẽ được cập nhật khi mỗi bản ghi đi vào, các trang sẽ được sắp xếp lại và điều đó làm mất thời gian và I / O của đĩa. Xây dựng các chỉ mục sau khi yêu cầu quét một bảng.

Không có quy tắc cứng và nhanh nào bạn có thể phải thử nghiệm với điều này tùy thuộc vào loại chỉ mục và dữ liệu liên quan. Các chỉ mục nên được xem xét thường xuyên khi nhu cầu / truy vấn thay đổi.


1
Tôi đã chạy tập lệnh này nhưng muốn có một hướng dẫn đơn giản để diễn giải nó.
IrishChieftain

0

Thử đi:

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 

Raj


0

Tôi đã thêm ngày và mã được sử dụng lần cuối để thả vào truy vấn của Raj.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.