我有一个表my_table
,其中列a
,b
,c
,d
,e
。
我有一个查询会对a
,b
和c
进行过滤,并返回d
和e
;我有另一个查询,可以对b
和c
进行过滤,并返回d
和e
。如果我创建以下索引:
CREATE NONCLUSTERED INDEX
ON my_table (a)
INCLUDE (b);
CREATE NONCLUSTERED INDEX
ON my_table (b,c)
INCLUDE (d,e);
第一个查询(对a
,b
,c
进行过滤)是否可以使用这两个索引?
SQL Server 2008 R2,如果重要的话。
答案 0 :(得分:0)
通常没有。
我听说在极少数情况下,SQL Server的后续版本可以使用多个索引进行一次操作,但是告诉我这个的人说他从未见过它实际发生过。
以这种方式思考,你将如何用C#编写代码?
只使用第一个索引,您将找到您的行,然后在聚集索引中为缺失的数据执行哈希表查找。
使用这两个索引,您将在第一个索引中找到您的行,然后使用嵌套循环执行完整索引扫描。也就是说,对于来自索引(out loop)的每个匹配记录,您将循环遍历第二个索引中的每个记录以查找匹配(内部/嵌套循环)。
或者使用两个索引,您将找到第一个索引中的所有行以及第二个索引中的所有行。然后你必须弄清楚如何根据主键加入两个列表,可能使用嵌套循环。
答案 1 :(得分:0)
如果给出两个查询以及它们看到的列,很难说它将使用哪些索引。索引使用完全基于统计信息,执行计划是围绕它构建的。即使您有一个索引,在一个足够小的表上,您将获得索引扫描而不是搜索只是因为它不会节省时间或读取以进行扫描搜索。
要告诉它将使用哪些索引,你需要知道a)表的大小b)a,b,c各自的独特之处c)基于b)的估计/实际执行计划。这决定了你的索引用法。服务器将使用它认为会以最快的速度获得结果的任何计划。
为了让服务器生成上面描述的Jonathan执行计划,需要一个相当特定的数据集。唯一(或几乎唯一)a,b,c用于使索引值得使用,深度和宽表将阻止密钥查找。当然,统计数据需要实际表示,以使执行计划考虑使用两个索引。
答案 2 :(得分:0)
是的,它被称为索引交集,https://www.brentozar.com/archive/2016/06/lets-make-match-index-intersection/。
然而,要发生这种情况,SQL Server必须确定每个索引搜索都会减少表中匹配行的总数,但仍然会导致返回多行,但是对两者的搜索交集会再次显着减少表中匹配行的数量与仅针对一个的查找次数。
因为我假设你真正的问题是你是否应该创建第三个索引来处理这个具有合理性能的查询,我的一般答案是否定的,你不应该。索引交集很可能是SQL Server在最糟糕的情况下使用的情况,在这种情况下,仅针对一个索引的查找不会显着过滤行以证明书签查找的合理性。
当且仅当针对两个当前索引的搜索结果返回大部分表行时,第三个索引可能是有益的,但两个结果的交集非常小。对于SQL Server来说,从两个分支中抽取那么多行并且行与行匹配可能比单个索引要重得多,以便返回非常少的行。只有你能够很好地了解你的数据,但似乎不太可能,并且很可能意味着你现有的两个索引当前没有足够的选择性来用于索引搜索。