Index optimization (2)

1) View invalid index information in the database

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) View all index information of the database

select indexs.Tab_Name as [table name], indexs.Index_Name as [index name], indexs. [Co_Names] as [index column],
        Ind_Attribute.is_primary_key as [whether primary key], Ind_Attribute.is_unique AS [whether unique key],
        Ind_Attribute .is_disabled AS [Whether to disable]
 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) / * Type of index: = heap / 1 = aggregation / 2 = non-aggregation / 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) Query the table without index

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 

---- By using the same query, you can use TableHasClusteredIndex instead of TableHasIndex property to find those tables without index clusters.


4) Check which indexes are in the table

Method 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-check all user tables

AND c .name = 'tablename' --Check the specified table

ORDER BY c. name ,

        a.name ,

        d.name

Method 2 :

sp_helpindex 'Tablename'

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

exec sp_spaceused 'tablename' view index size  


Under what circumstances the index is invalid:

1. As long as the function is used on the column, the index of the column will not work, such as: substring (aa, 1,2) = 'xx'

2. As long as the column is calculated, the index of the column will not work, such as: aa + 10 = 20

3. In some cases of LIKE operation, the index of this column will not work, such as: aa LIKE '% 10%'

4. In some cases, using the reverse operation, the index of the column will not work, such as: aa <> 2

5. When using OR in WHERE , there is a column without index, then the index of other columns will not work

Several principles for creating clustered indexes:

1. The clustered index is unique

2. Frequently used for sorting, grouping, range query

3. Do not build a clustered index on frequently updated columns, because the value change will cause the adjustment of the physical storage of records

Summarize when to use clustered or non-clustered indexes (very important)

  Action description clustered index non-clustered index                            

Packet ordering frequently column should be                              

Returns a certain range of data should not                        

One or very few different values should not be                         

A small number of different values should not                                 

A large number of different values should not be                              

Frequently updated columns should not be                                  

The primary and foreign key columns should be                                          

Frequently modify index column should not be                              

Index usage experience summary

1 ) Using an aggregate index is faster than using a primary key that is not an aggregate index.

2 ) Using an aggregate index is faster than using an ordinary primary key to do order by , especially in the case of a small number

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

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


:::


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

Guess you like

Origin blog.csdn.net/qyx0714/article/details/72834335