索引或不索引 - 是否有理由索引已包含在主键中的列?

时间:2013-07-25 13:12:20

标签: sql-server

如果我有一个在三列上定义主键的表,那么为三列中的每一列创建单独的附加索引是否有任何意义?

我在他们已经完成此操作的客户站点遇到了一个数据库,在我看来它适得其反,因为这些列已经被索引了,因为集群PK索引,并且其他索引在不提高搜索性能的情况下增加了插入开销。

但是数据库是一种黑色艺术,所以在提出建议之前,我希望得到更广泛的意见。

主要关注的是Sql Server,但在使用Oracle的站点上也可能出现这种情况。

3 个答案:

答案 0 :(得分:3)

所以你有一个包含两列或更多列的索引键。对于这样的索引,列的顺序很重要。

例如:如果索引键是(ColA,ColB,ColC)CREATE INDEX MyIndexName ON MySchema.Mytable(ColA,ColB,ColC) ...),则SQL Server(默认情况下)can't skip在第一列(ColA)上搜索第二栏(ColB)。对于复合索引,如果存在一个相等的谓词(通常此模板<Column> = <Constant>但是读取我的答案的最后一段),SQL Server可以在列上搜索上一列:

[1] SARGable&lt; =&gt;索引寻找以下谓词(仅举几个例子)

WHERE ColA=@p1
WHERE ColA<=@p1
WHERE ColA>@p1
WHERE ColA=@p1 AND ColB=@p2
WHERE ColA=@p1 AND ColB=@p2 AND ColC=@p3
WHERE ColA=@p1 AND ColB=@p2 AND ColC<=@p3
WHERE ColA=@p1 AND ColB=@p2 AND ColC>@p3
.. For a complete picture please read SQLMag article from the last paragraph

[2]不是SARGable或者不是完全SARG的以下谓词(仅举几个例子)

WHERE ColB=@p2因为在前一列上缺少一个相等的谓词:ColA 在这种情况下,使用此键(ColB)的索引可能很有用。

WHERE ColA>=@p1 AND ColB=@p2因为第一列没有相同的谓词:ColA。在这种情况下,使用此键(ColB,ColA)的索引可能很有用。

WHERE ColA=@p1 AND ColB<=@p2 AND ColC=@p3因为第二列(ColB)上的谓词不相等。在这种情况下,使用其中一个键(ColA,ColC,ColB)(ColC,ColA,ColB)的索引可能很有用。

有关此主题的更多信息(SARGable):link;

这意味着,如果您有一个包含此键(ColA,ColB,ColC)的索引,那么这些索引(ColB)(ColB,ColA)(ColA,ColC,ColB)(ColC,ColA,ColB) 可能是,也很有用。

答案 1 :(得分:1)

根据您的应用程序,您可以决定哪种方法最适合表中其他列的索引。例如,如果您有大量查询(包括某些列),则将它们包含为索引可能是有意义的。您可以在每列中包含一个索引,也可以创建一个“覆盖索引”,其中可能包含您知道将由应用程序经常在SQL查询中返回的其他列。

以下是其他一些有用的建议:

  1. 您可以使用“Display Estimated Execution Plan”运行SQL Management Studio并发出一些SELECT / INSERT / UPDATE / DELETE查询。这将为您提供DBMS在幕后所做工作的可视化图表。如果您看到“表扫描”或“索引扫描”,则可以通过添加索引来更改“表搜索”或“索引搜索”来提高性能,这样可以提高效率。

  2. 您可以安装名为SQL Performance Dashboard的工具。这是一个很棒的工具,由Microsoft提供,它将实际检查应用程序中针对您的数据库的查询/事务,并提供SSRS报告,其中包含有关添加索引的位置的建议提示等。仪表板报告可用于SQL Server 2008及更高版本

答案 2 :(得分:1)

要在本课题正文中回答您的问题,是的,在为一列创建索引时,有一点(几个,真的),即使该列是主键的一部分。一个这样的观点是数据库引擎可以使用更具选择性的索引,特别是如果只有该选择性索引中的列与正在执行的查询或命令相关。可以使用更具选择性的索引的一个原因是对于具有多列的索引,索引中的列的顺序是重要的;如果第一列不相关,则不能必然使用多列索引。