如果我有一个在三列上定义主键的表,那么为三列中的每一列创建单独的附加索引是否有任何意义?
我在他们已经完成此操作的客户站点遇到了一个数据库,在我看来它适得其反,因为这些列已经被索引了,因为集群PK索引,并且其他索引在不提高搜索性能的情况下增加了插入开销。
但是数据库是一种黑色艺术,所以在提出建议之前,我希望得到更广泛的意见。
主要关注的是Sql Server,但在使用Oracle的站点上也可能出现这种情况。
答案 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查询中返回的其他列。
以下是其他一些有用的建议:
您可以使用“Display Estimated Execution Plan”运行SQL Management Studio并发出一些SELECT / INSERT / UPDATE / DELETE查询。这将为您提供DBMS在幕后所做工作的可视化图表。如果您看到“表扫描”或“索引扫描”,则可以通过添加索引来更改“表搜索”或“索引搜索”来提高性能,这样可以提高效率。
您可以安装名为SQL Performance Dashboard的工具。这是一个很棒的工具,由Microsoft提供,它将实际检查应用程序中针对您的数据库的查询/事务,并提供SSRS报告,其中包含有关添加索引的位置的建议提示等。仪表板报告可用于SQL Server 2008及更高版本
答案 2 :(得分:1)
要在本课题正文中回答您的问题,是的,在为一列创建索引时,有一点(几个,真的),即使该列是主键的一部分。一个这样的观点是数据库引擎可以使用更具选择性的索引,特别是如果只有该选择性索引中的列与正在执行的查询或命令相关。可以使用更具选择性的索引的一个原因是对于具有多列的索引,索引中的列的顺序是重要的;如果第一列不相关,则不能必然使用多列索引。