聚簇索引是否比包含?的非聚集索引更快?

时间:2013-05-14 20:42:46

标签: sql sql-server sql-server-2008

我有一个包含a,b,c,d,e,f,g列的表格,大约有500,000行。

有一个查询经常运行SELECT * FROM table WHERE a = @a AND b = @b AND c = @c

最好是在a,b和c, OR 上创建clustered index我最好在a,b和c {{上创建non-clustered index 1}}。

自发出select *以来,不确定include会帮助加快查询速度。

任何帮助将不胜感激!

4 个答案:

答案 0 :(得分:13)

聚集索引将是SELECT最快,但它可能不一定是正确的选择。

聚簇索引确定记录的物理存储顺序(这就是为什么每个表只能有一个)。因此,虽然它对于THAT查询来说是最快的,但它可能会减慢其他查询的速度,并且如果其中一个列发生更改,则可能会更新和插入Kill,这可能意味着需要在物理上重新定位记录。

如果更新了任何这些字段(包括所包含的字段),则INCLUDE将再次加速该查询,代价是额外的存储和额外的索引维护。

我会在a,b和c上使用非聚集索引启动,看看是否可以将性能提升到合理的水平。任何更多的东西都可能只是在一个区域内交易速度缓慢而另一个区域。

答案 1 :(得分:1)

聚集索引会更快。

使用SELECT *,您的群集和非群集(包含所有)都包含每个页面中的所有列。但是,非聚集索引ALSO包含一个返回聚簇键的引用 - 如果向表中添加更多列,则需要这样做,但实际上也是因为所有索引(索引视图除外)都是指向数据页的指针。 NCI不会显示新列(固定的包含列表),但数据页将会显示。

SQL Server 可能足够智能,可以发现NCI上的INDEX SCAN(+包含)可以实现SELECT *,而无需书签查找数据页面,但是即使这样,索引扫描也会比等效的聚簇索引扫描宽一列。

拥有3列聚类键通常不是一个好主意。您可以考虑使用简单的单列标识聚类键,并创建围绕3列聚集的索引视图。

答案 2 :(得分:1)

您的主题中所述问题的答案一般是否定的。因为你通常更喜欢使用最窄的覆盖(可能是非聚集的)索引。

但是在你的情况下你选择*所以如果聚集索引足够匹配你的搜索条件它总是会被选中,因为任何更窄的东西都需要进行书签查找。

所以这引发了一个很大的问题,为什么这个查询就是这样,是否有更好的选择聚类索引一般适用于您的应用程序(窄,静态,增加,唯一),以及您是否真的需要得到所有列。因为你提供的两个选项都不是典型的优秀设计。

500000行相当小,但如果性能有问题,您希望查看每页适合的行数,以及是否可以提高查询中的选择性并覆盖非聚集索引。< / p>

答案 3 :(得分:-3)

您的聚簇索引是数据存储在表中的顺序,因此每个表只能有一个聚簇索引。如果您创建一个新索引(默认情况下为非群集),请确保在索引中定义的列的顺序与WHERE子句中使用的顺序相同,这将允许SQL执行直接索引扫描以查找您的记录。寻找。