索引优化(二)

1)查看数据库中无效索引信息

SELECT  ind.index_id ,  
       obj.name AS TableName ,  
       ind.name AS IndexName ,  
       ind.type_desc ,  
       indUsage.user_seeks ,  
       indUsage.user_scans ,  
       indUsage.user_lookups ,  
       indUsage.user_updates ,  
       indUsage.last_system_seek ,  
       indUsage.last_user_scan ,  
    'drop index [' + ind.name + '] ON [' + obj.name + ']' AS DropIndexCommand  
 FROM    sys.indexes AS ind  
         INNER JOIN sys.objects AS obj ON ind.object_id = obj.object_id  
         LEFT JOIN sys.dm_db_index_usage_stats indUsage ON ind.object_id = indUsage.object_id  
         AND ind.index_id = indUsage.index_id  
WHERE   ind.type_desc <> 'HEAP'  
        AND obj.type <> 'S'  
        AND OBJECTPROPERTY(obj.object_id, 'isusertable') = 1  
        AND ( ISNULL(indUsage.user_seeks, 0) = 0  
        AND ISNULL(indUsage.user_scans, 0) = 0  
        AND ISNULL(indUsage.user_lookups, 0) = 0 )  
        and obj.name='table'  -------根据指定表进行检测
ORDER BY obj.name ,ind.name


2)查看数据库所有索引信息

select    indexs.Tab_Name  as [表名],indexs.Index_Name as [索引名] ,indexs.[Co_Names] as [索引列],
        Ind_Attribute.is_primary_key as [是否主键],Ind_Attribute.is_unique AS [是否唯一键],
        Ind_Attribute.is_disabled AS [是否禁用]
 from (
    select Tab_Name,Index_Name, [Co_Names]=stuff((select ','+[Co_Name] from 
    (    select tab.Name as Tab_Name,ind.Name as Index_Name,Col.Name as Co_Name from sys.indexes ind 
        inner join sys.tables tab on ind.Object_id = tab.object_id and ind.type in (1,2)/*索引的类型:=堆/1=聚集/2=非聚集/3=XML*/
        inner join sys.index_columns index_columns on tab.object_id = index_columns.object_id and ind.index_id = index_columns.index_id
        inner join sys.columns Col on tab.object_id = Col.object_id and index_columns.column_id = Col.column_id
    ) t where Tab_Name=tb.Tab_Name and Index_Name=tb.Index_Name  for xml path('')), 1, 1, '')
    from (
        select tab.Name as Tab_Name,ind.Name as Index_Name,Col.Name as Co_Name from sys.indexes ind 
        inner join sys.tables tab on ind.Object_id = tab.object_id and ind.type in (1,2)/*索引的类型:=堆/1=聚集/2=非聚集/3=XML*/
        inner join sys.index_columns index_columns on tab.object_id = index_columns.object_id and ind.index_id = index_columns.index_id
        inner join sys.columns Col on tab.object_id = Col.object_id and index_columns.column_id = Col.column_id
    )tb
    where Tab_Name not like 'sys%'
    group by Tab_Name,Index_Name
) indexs inner join sys.indexes  Ind_Attribute on indexs.Index_Name = Ind_Attribute.name
order by indexs.Tab_Name


3)查询没有建立索引的表

SELECT (SELECT si.rows
    FROM sysindexes si
    WHERE si.id = so.id and indid = 0) rows
, so.name
FROM sysobjects so
WHERE so.xtype = 'U'
    AND OBJECTPROPERTY(so.id , 'TableHasIndex' ) = 0
ORDER BY 1 DESC 

----通过使用同样的查询,你可以用TableHasClusteredIndex替代TableHasIndex属性来查找那些没有索引簇的表。


4)查看表中有哪些索引

方法1

SELECT  indexname = a.name , tablename = c. name ,indexcolumns = d .name , a .indid

FROM    sysindexes a JOIN sysindexkeys b ON a .id =b .id  AND a .indid = b.indid

        JOIN sysobjects c ON b .id = c .id

        JOIN syscolumns d ON b .id = d .id  AND b .colid = d .colid

WHERE   a .indid NOT IN ( 0 , 255 ) 

-- and   c.xtype='U'  and   c.status>0 -- 查所有用户表

AND c .name ='tablename' --查指定表

ORDER BY c. name ,

        a.name ,

        d.name

方法2

sp_helpindex 'Tablename'

-----------------------

exec sp_spaceused 'tablename'   查看索引大小


索引在哪种情况下失效:

1.只要对列使用函数,该列的索引将不起作用,如:substring(aa,1,2)='xx'

2.只要对列进行计算,该列的索引将不起作用,如:aa+10=20

3.某些情况下的LIKE操作,该列的索引将不起作用,如:aa LIKE '%10%'

4.某些情况使用反向操作,该列的索引将不起作用,如:aa <>2

5.WHERE中使用OR时,有一个列没有索引,那么其它列的索引将不起作用

创建聚集索引的几个原则:

1、聚集索引唯一

2、频繁用于排序、分组、范围查询

3、不要在频繁更新的列上建聚集索引、因为值的变动,会引起记录物理存储的调整

总结何时使用聚集索引或非聚集索引(很重要)

  动作描述                       聚集索引      非聚集索引

列经常被分组排序                              

返回某范围内的数据                         不应

一个或极少不同值          不应               不应

小数目的不同值                                 不应

大数目的不同值              不应                

频繁更新的列                  不应                

主、外键列                                          

频繁修改索引列              不应                

索引使用经验总结

1)用聚合索引比用不是聚合索引的主键速度快。

2)用聚合索引比用一般的主键做order by时速度快,特别是在小数量情况下

3)使用聚合索引内的时间段,搜索时间会按数据占整个数据表的百分比成比例减少,而无论聚合索引使用了多少个

4)日期列不会因为分秒的输入而减慢查询速度


:::


发布了22 篇原创文章 · 获赞 7 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qyx0714/article/details/72834335