当现有索引包括新索引中的所有列时,为什么创建此新索引会大大提高性能?


19

我有Log和LogItem表;我正在编写查询以从这两者中获取一些数据。有成千上万个Logs,每个Log最多可以有125个LogItems

有问题的查询很复杂,因此我跳过了它(如果有人认为它很重要,可以将其发布),但是当我运行SSMS估计查询计划时,它告诉我一个新的非聚集索引可以将性能提高多达100% 。

Existing Index: Non-clustered
Key Colums (LogItem): ParentLogID, DateModified, Name, DatabaseModified

Query Plan Recommendation
CREATE NONCLUSTERED INDEX [LogReportIndex]
ON [dbo].[LogItem] ([ParentLogID],[DatabaseModified])

只是为了好玩,我创建了这个新索引并运行了查询,令我惊讶的是,现在查询运行大约需要1秒钟的时间,而这才是10秒钟以上。

我以为现有索引可以覆盖这个新查询,所以我的问题是,为什么在新查询中仅使用的列上创建新索引会提高性能?我应该为where子句中使用的每种唯一组合的列都有索引吗?

注意:我不认为这是因为SQL Server正在缓存我的结果,在创建索引之前,我运行查询约25-30次,并且始终花了10-15秒,而在索引之后,索引一直都在〜1或更少。


在创建其他非聚集索引之前,实际执行计划针对索引使用情况显示了什么?
Thomas Stringer

什么是将性能提高100%?

@鲨鱼好问题,我不确定。这是我的第一个性能调试情况。我一定会抓住这个机会。它说的只是“缺少索引”,并且说出哪些字段。

@JeffO这就是SSMS所说的:“查询处理器估计,实现以下索引可以使查询成本降低100%。”

Answers:


21

索引中列的顺序很重要。如果过滤需要索引中的第1列和第4列,则索引将无济于事。仅在按前N个连续列进行过滤时才有用。

这是因为索引是一棵树。你不能有效地选择树在那里的所有节点column3 = something,因为它们散布所有其他的地方,属于不同的价值观column1column2。但如果你知道column1column2以及,定位在树分支,在右侧是没有道理的。


那么可以安全地假设(通常)将要到达该表的每组“ where”子句需要一个索引吗?

我曾经通过确保以正确的顺序使用索引来大大加快了其他人的查询。

1
@Nate广泛地说,是的。有些where可能重叠,因此您的索引可能覆盖了几个wheres。或者您可以忽略where子句的某些部分,因为对特定列的索引仍然无济于事(选择性低);但总的来说,是的。

@Nate您不希望有多余的索引。SQL必须维护的每个索引都会增加其自身的开销。如果您可以对WHERE子句重新排序以匹配现有索引的前N列,则可以使您非常接近而无需添加其他索引。
那个查克·盖伊(Chuck Guy)

1
@ChuckBlumreich where子句中列的顺序并不重要。服务器将始终对其进行排列,以充分利用现有索引。拥有一个包含所有必需where列作为其第一列的索引只是一个问题。

12

前沿的指数是最重要的。

只要您的查询被索引的前沿“覆盖”,它就会很有效。数据库索引通常实现为B树,并且B树的结构规定必须按一定顺序进行搜索,这就是为什么复合索引中字段顺序很重要的原因。

如果您有“漏洞”,例如,如果在ParentLogID和上搜索DatabaseModified,而仅在上进行索引{ParentLogID, DateModified, Name, DatabaseModified},则仅{ParentLogID}索引的一部分可以得到有效利用。

(注意:某些DBMS可以{DatabaseModified}通过“跳过扫描” 来利用该部分,但是即使您的DBMS这样做,它的效率也比常规索引访问低得多)


因此,如果我拥有Columns (a, b, c, d, e, f)大多数查询,那么... WHERE A IN(...) AND B = 3我的索引Index(a,b,c,d)是一个很好的索引,但是如果我拥有索引,这无济于事,... WHERE A IN (...) AND D = 5这就是为什么我制作的新索引Index(a,d)大大提高了性能,对吗?

8
@Nate-正确。可以把它想像成电话簿。如果您只知道某人的名字,就无法翻阅整本书,因为它是按照姓氏
JNK
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.