2009-06-01 4 views
0

인덱스를 삭제하기 위해 프로덕션 환경에서 사용되지 않는 인덱스를 찾기 위해 쿼리를 작성했습니다. 그러나 last_user_update 열이 색인이 전적으로 유지 관리 오버 헤드라는 표시인지 여부가 궁금합니다. 그것을 삭제하는 것이 좋을 것입니다, 또는 인덱스가 insert/update/delete 구문의 수행을 도왔는지, 나는 그것을 버리고 싶지 않을 것입니다. 다음은 사용하고자하는 쿼리입니다.MSSQL : last_user_update는 인덱스가 성능을 저하시키는 것을 의미합니까?

DECLARE @DBInfo TABLE 
(database_id int, object_id int, tablename nvarchar(200), indexname nvarchar(200), lastactivity datetime) 

DECLARE @command VARCHAR(5000) 

SELECT @command = 'Use [' + '?' + '] SELECT 
database_id, o.object_id, o.name, i.name as indexname, max(lastactivity) as lastactivity 
from (
    select database_id, object_id, index_id, max(last_user_seek) as lastactivity from sys.dm_db_index_usage_stats 
    WHERE object_id > 1000 
    GROUP BY database_id, object_id, index_id 
    UNION ALL 
    select database_id, object_id, index_id, max(last_user_scan) as lastactivity from sys.dm_db_index_usage_stats 
    WHERE object_id > 1000 
    GROUP BY database_id, object_id, index_id 
    UNION ALL 
    select database_id, object_id, index_id, max(last_user_lookup) as lastactivity from sys.dm_db_index_usage_stats 
    WHERE object_id > 1000 
    GROUP BY database_id, object_id, index_id 
    /*UNION ALL 
    select database_id, object_id, index_id, max(last_user_update) as lastactivity from sys.dm_db_index_usage_stats 
    WHERE object_id > 1000 
    GROUP BY database_id, object_id, index_id*/ 
) a 
inner join sys.objects o on a.object_id = o.object_id 
inner join sys.indexes i on i.object_id = a.object_id AND i.index_id = a.index_id 
where database_id = db_id() 
GROUP BY database_id, o.object_id, o.name, i.name 
order by lastactivity' 
INSERT INTO @DBInfo 
    (database_id, object_id, tablename, indexname, lastactivity) 
EXEC sp_MSForEachDB @command 

SELECT db_name(database_id) as dbname, tablename, indexname, lastactivity FROM @DBInfo 
where lastactivity < dateadd(day, -15, getdate()) or lastactivity is null 
order by db_name(database_id), tablename, indexname 

답변

2

사용하지 않는 인덱스를 확인하는 데는 열의 의미가 없습니다.

인덱스는 최근 업데이트가 없지만 (예 : 테이블 스캔을 피하거나 인기있는 쿼리를 처리하는 등) 여전히 유용 할 수 있습니다. 이 쿼리는 인덱스를 사용하는 방법을 알려줍니다 : 주석 후

SELECT 
    o.name AS [object_name], 
    i.name AS index_name, 
    i.type_desc, 
    u.user_seeks, u.user_scans, 
    u.user_lookups, u.user_updates, 
    o.type 
FROM 
    sys.indexes i 
    JOIN 
    sys.objects o ON i.[object_id] = o.[object_id] 
    LEFT JOIN 
    sys.dm_db_index_usage_stats u ON i.[object_id] = u.[object_id] AND 
            i.index_id = u.index_id AND 
            u.database_id = DB_ID() 
WHERE 
    o.type IN ('U', 'V') AND 
    i.name IS NOT NULL 
ORDER BY 
    o.name, i.NAME; 

편집 :

내가 인덱스가 사용되는 방법을 나에게 말해 user_seeks, user_scans, user_lookups and user_updates 열을 선호합니다. 참고로, 나는 위의 쿼리를 사용하고 "system_updates"열을 포함하지만 모든 값에 대해 0을 가지고 (SQL 2005, 우리가 전에 좋은 효과를이 사용했습니다 50Gb에 정도 데이터베이스) sys.dm_db_index_usage_stats

에서

user_updates 카운터는 기본 테이블에서 작업 또는 뷰를 삽입, 업데이트 또는 삭제함으로써 인덱스 에서 유지 관리 수준이 임을 나타냅니다. 이보기를 사용하여 응용 프로그램에서 가볍게 만 사용되는 색인을 결정할 수 있습니다. 도 뷰를 사용하여 오버 헤드가 인 인덱스를 결정할 수 있습니다. 유지 관리 오버 헤드가 발생하지만쿼리에 사용되는 사용되지 않는 인덱스를 삭제하는 것이 좋습니다. 그들이 사용 여부를 당하고 있는지 여부 - -

그래서, 마지막 문장은 인덱스의 동적 속성에 관심이 있다면

+0

감사합니다. 나는 user_updates 칼럼이 같은 질문을 던지기를 상상한다 : 나쁘지 않습니까? user_updates가 데이터 수정의 수행을 돕거나 해를 입혔습니까? –

+0

추가 정보. 실제로이 칼럼을 사용하지 않았습니다 : 우리는 주로 사용법을 보았습니다. – gbn

1

을 사용 볼뿐만 아니라 업데이트하는 의미 당신이 더 좋을 수도 DMV에서 문의하십시오 - Dynamic Management Views. 그들은 색인이 사용되는 빈도와 빈도에 대한 좋은 정보를 제공해야합니다.

또한 실제로는 쿼리 최적화 프로그램의 내부 통계를 사용하여 실적을 높일 수있는 색인이 누락 될 가능성이 있고 잠재적으로 사용하지 않는 색인을 표시하는 다른 하나를 제안하는 DMV가 있습니다.

동적보기 관리보기 - 모든 서버를 다시 부팅 할 때마다 재설정되므로 영구 재설정 기간 동안 데이터를 수집하지 않습니다. 마지막 재설정 이후에만.

마크

누락을 발견 한 지수 :

SELECT 
    object_name(object_id), d.*, s.* 
FROM 
    sys.dm_db_missing_index_details d 
INNER JOIN 
    sys.dm_db_missing_index_groups g ON d.index_handle = g.index_handle 
INNER JOIN 
    sys.dm_db_missing_index_group_stats s ON g.index_group_handle = s.group_handle 
WHERE 
    database_id = db_id() 
ORDER BY 
    object_id 

찾기 사용되지 않는 인덱스 : 귀하의 코멘트에 대한

DECLARE @dbid INT 

SELECT @dbid = DB_ID(DB_NAME()) 

SELECT 
    OBJECTNAME = OBJECT_NAME(I.OBJECT_ID), 
    INDEXNAME = I.NAME, 
    I.INDEX_ID 
FROM  
    SYS.INDEXES I 
JOIN 
    SYS.OBJECTS O ON I.OBJECT_ID = O.OBJECT_ID 
WHERE  
    OBJECTPROPERTY(O.OBJECT_ID, 'IsUserTable') = 1 
    AND I.INDEX_ID NOT IN (SELECT S.INDEX_ID 
          FROM SYS.DM_DB_INDEX_USAGE_STATS S 
          WHERE S.OBJECT_ID = I.OBJECT_ID 
            AND I.INDEX_ID = S.INDEX_ID 
            AND DATABASE_ID = @dbid) 
ORDER BY 
    OBJECTNAME, 
    I.INDEX_ID, 
    INDEXNAME ASC 
관련 문제