最好使用聚集索引还是包含列的非聚集索引?

4
当我查看特定查询的执行计划时,发现77%的成本在于聚集索引搜索。
使用聚集索引是否意味着我不会因为输出的列而遇到性能问题?
是否最好创建一个包括所有输出列的非聚集版本?
更新: 聚集索引使用复合键。不确定这是否有差异。

这里提供的信息太少了,无法给出一个好的建议。你的表是什么样子的?有哪些字段?哪些字段被索引了?你最常用的查询是什么样子的? - marc_s
成本是相对的:你能给我们提供更多信息吗? - davek
嗯,您还需要什么信息?占据77%成本的子树使用了约97%的经过时间和约60%的CPU时间。最终返回了接近600,000条记录。 - Abe Miessler
嗯,查询计划的子树占了77%的空间,还是聚集索引本身占了77%的空间?你的查询返回了600,000行数据;我想你关心的是它需要多长时间(无论那个时间是多少)?600,000行数据是相当大的数据量。将其发送到客户端需要一段时间。你确定是执行时间有问题,还是传输时间有问题吗?如果不是问题所在,你不会想浪费太多时间来改进查询。 - Disillusioned
这是索引查找本身。我如何确认它是执行时间而不是传输时间? - Abe Miessler
显示剩余5条评论
3个回答

4
在非聚集索引中使用包括列的原因是为了避免对聚集数据进行“书签查找”。问题是,如果SQL Server 理论上可以使用特定的非聚集索引,但优化器估计会有“太多”的书签查找,则该索引将被忽略。但是,如果所有选定的列都可以直接从索引中访问,则不需要进行书签查找。
在您的情况下,通过“聚集索引查找”访问数据非常有前途。很难提高其性能。包括所有选定列的非聚集索引可能会稍微快一些,但仅因为原始数据略少。(但不要忘记增加插入/更新时间的成本。)
但是,您应该检查细节...
  • 如果您正在使用组合键,并且查找实际上仅限于键的开头,则您可能就没有那么幸运了。您可能会发现查找仅缩小到500,000行,然后基于其他标准搜索该行。在这种情况下,请尝试使用一些非聚集索引。
  • 聚集索引查找本身可能很好;但是,如果由于某些其他方面效率低下而返回太多行而进行100,000次查询,则通过改善聚集索引查找的性能不会获得多少收益。
最后,为了详细说明davek的评论:“成本是相对的”。仅因为聚集索引占查询成本的77%并不意味着存在问题。可能编写一个微不足道的单表查询,返回单个行和聚集索引查找成本为100%。(但是当然,作为唯一的“工作”,它将是100%的工作...而且100%的瞬间仍然是瞬间
所以:“不要担心;保持愉快!”

你关于复合键的评论非常有趣。这个特定的索引是一个复合键。你能详细说明一下“尝试使用非聚集索引”的意思吗? - Abe Miessler
3
假设你的聚集索引是基于(A,B,C),但查询根据A和C进行过滤。那么聚集索引可以进行查找,但效率不会达到最优(即只会在A上进行查找)。基于(A,C)或(C,A)的非聚集索引可能更有效。如果筛选器返回少量行,则很好-只需进行一些书签查找,查询将运行得相当高效。然而,如果它返回许多行,则书签查找就不再有效,并且索引将被忽略。因此,请尝试添加包含列。首先尝试哪些列将取决于您查询的其余部分。 - Disillusioned

1

您已经有了一个搜索,因此好处可能很小。

不过您可以尝试一下。选项:

  • 第二个非聚集索引,保留原始
  • 将聚集索引移动到另一列

还有其他好的聚集候选项吗?请注意,您始终需要一个唯一的聚集索引(因为唯一标识符 + 这里是SO + 这里)。当然,您的PK是什么?


我有一个组合主键。构成主键的两列是正在使用的聚集索引中的两列。 - Abe Miessler

0

这取决于你所讨论的列数,如果只有几列,那么非聚集索引的性能会更好;如果选择了大部分列,则聚集索引更好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接