主键列上的非聚集索引?

时间:2013-11-18 20:22:36

标签: sql-server performance sql-server-2008 indexing

我在表上有一个主键(比如ContactID)。 SQL Server自动在此列上创建和维护聚簇INDEX。当我运行Tuning Advisor时(针对性能跟踪),它似乎建议在同一列上使用另一个INDEX - contactID列上的NON CLUSTERED索引。这将如何帮助 - 因为列上已经有聚簇索引?

2 个答案:

答案 0 :(得分:9)

在非常特定的情况下,例如包含ContactID的表很大,和/或行很大(即大量的varchars),扫描聚簇索引与使用ContactID作为聚簇相比可能非常IO /内存密集索引和非聚集索引。

如果查询需要通过ContactID扫描表,并且ContactID上只有一个Clustered Index,则从磁盘读取整行数据。但是,如果ContactID上也有非群集索引,则只从磁盘读取ContactID。

这与Clustered vs Non Clustered存储在磁盘上的方式有关。群集索引由ContactID存储,但所有行数据也与其一起存储。假设每行足够大以占用一页(8KB),那么扫描100,000,000行需要800,000,000 kb的磁盘io。

非群集索引只会在其“行”中存储ContactID。假设ContactID是8个字节(bigint),那么1000个非聚集索引可以放在一个页面(8KB)中。现在,通过ContactID扫描100,000,000行只需要(100,000,000 / 1000 * 8)= 800,000 KB的磁盘io。

如果被分析的查询被频繁调用,则800,000 KB与800,000,000 KB相比非常重要。

但是,正如Evadman建议的那样,Tuning Advisor只关注特定的工作负载。在大多数情况下,额外的非群集索引只是插入/删除的额外工作量。

现实生活中的例子,我使用了一个包含大量varchars的表。聚集索引是5521 MB。有几个查询,每秒调用很多次,最终会对Clustered Index列进行部分扫描(让我们称之为P_ID)。 P_ID上的非聚簇索引是211 MB(比聚集Idx小26倍)。这导致查询执行时间以及磁盘和内存的负载大幅减少。

Bonus:查询以查找Clustered和Non Clustered索引的大小

DECLARE @TableName VARCHAR(200)
SET @TableName = 'NAME_OF_YOUR_TABLE'

SELECT
    OBJECT_NAME(i.OBJECT_ID) AS TableName,
    i.name AS IndexName,
    i.index_id AS IndexID,
    8 * SUM(a.used_pages) AS 'Indexsize(KB)',
    (8 * SUM(a.used_pages)) / 1024 AS 'Indexsize(MB)'
FROM sys.indexes AS i
JOIN sys.partitions AS p 
    ON p.OBJECT_ID = i.OBJECT_ID AND p.index_id = i.index_id
JOIN sys.allocation_units AS a 
    ON a.container_id = p.partition_id
WHERE OBJECT_NAME(i.object_id) = @TableName
GROUP BY i.OBJECT_ID,i.index_id,i.name
ORDER BY OBJECT_NAME(i.OBJECT_ID),i.index_id

答案 1 :(得分:3)

如果查询调优顾问在主键上推荐非聚集索引,它还会在另一列(或多列)上推荐聚簇索引。

主键是约束,而不是索引。 MS SQL Server的假设是主键也是从表中检索数据的主要方式(通过'where ContactID = 2'或ContactID上的表之间的连接)。该假设意味着还会在构成主键的列上自动创建聚簇索引。这种行为还有其他原因,但现在让我们保持这个简单。

现在,如果针对该表的大多数查询都是联系人名字(ContactFirstName字段),例如'Where ContactFirstName LIKE'Much%',那么SQL服务器将建议将聚簇索引从ContactID更改为ContactFirstName,因为表格只能有1个聚簇索引。主键约束仍然存在(并防止欺骗行),但表中的数据将按ContactFirstName进行物理排序。

调优顾问消耗的工作量将决定调整顾问推荐的内容。调整顾问还将仅使用工作负载中最高资源查询的百分比,而不是整个工作负载来进行确定。