2015-06-16 27 views
1

我在SQL Server上有一个包含约1000万行的表。它看起来一个非聚集索引ClearingInfo_idx像:SQL Server没有使用适当的索引进行查询

enter image description here

我正在运行未使用ClearingInfo_idx指数和执行计划的查询看起来是这样的:

enter image description here

任何人都可以解释为什么查询优化器选择扫描聚集索引?

+0

您可以尝试更新统计信息或重建索引(如果碎片较高)。如果这没有帮助,那么你的索引可能不够合理(实际上,使用'varchar(255)'作为索引中的第一列听起来像是一个可怕的想法)。您可以尝试添加管理工作室建议的索引 - 对于您尝试运行的查询,它的组织性更好。但是,您可能想要将[[status]]列更改为某个ID而不是'varchar(255)'。 – Luaan

+0

我试着更新统计数据,重建索引不是一个好主意,因为当前索引的碎片是3-5%。我无法更改status varchar(255),因为它是从第三方应用程序运行的。你能解释为什么建议的指数比我好? –

+2

那么,大小是非常重要的。用倒序的顺序,你首先寻找一个字节(我认为它实际上只是0或1),然后再四个字节。通过varchar寻找有点棘手,尤其是因为它的情况(也许重音)不敏感。总而言之,varchar列几乎在任何情况下都会损害您的性能 - 这会使索引变得庞大,这对其使用来说是一个巨大的损失。这可能是*忽略*索引是给定数据布局的最佳选择 - 特别是考虑到索引没有覆盖('select *'确实没有帮助)。 – Luaan

回答

0

我认为它建议这个索引,因为你使用一个尖锐的搜索立即两个列和clearingOrder_clearingOrderId。这些值是数字,很适合搜索。列状态是nvarchar,它不是搜索的最佳选择,并且由于您使用in进行搜索,SQL Server需要搜索其中的两个值。

SQL Server将使用两个数字列来获得更快的结果并在第二轮中的状态搜索后,由于对两个数字列进行精确搜索而减少了可能结果的数量。

希望你能得到我的意见。 :-)否则,再问一遍。 :-)

0

正如Luaan已经指出的那样,该系统更喜欢可能的原因扫描聚集索引是因为

  • 你问要返回所有字段(SELECT *),这改变域(索引字段+聚集索引字段)中存在,并且您可能会仅使用索引来查看它。如果您需要一些额外的字段,您可以考虑索引中的那些字段。
  • 索引字段的顺序不是非常优化的。另外,该领域的“内容”也可能不是很有帮助。索引栏中有多少个不同的值,它们是如何传播的?如果你是WHERE覆盖了90%的记录,那么很少有理由首先创建一个(巨大的)密钥列表,然后稍后从聚集索引中获取这些列表。直接扫描后者则更有意义。

您是否尝试了建议的索引?不确定在桌面上运行了哪些其他查询,但对于此特定查询,它似乎是对我的有效替代品。如果替换将满足其他查询是另一个课程的问题。添加额外的索引可能会对您的IUD操作产生负面影响,并且需要更多的磁盘空间;没有免费的午餐=) 这就是说,如果表现是一个问题,你有没有考虑过滤索引? (再次,没有免费午餐这样的事情;这都是关于优先事项)