Rah*_*van 7 index sql-server-2008 sql-server execution-plan
我正在 SQL Server 2008 上执行查询:
SELECT col1
FROM table1
WHERE col2=val2 AND col3=val3
Run Code Online (Sandbox Code Playgroud)
这里 col2 有一个非聚集索引, col1 是PRIMARY KEY
,而 col3 没有任何索引。查询执行计划与此类似。
我想知道这里的查询执行是如何工作的。从执行计划中,我可以看到“col2”上的索引查找和“col3”上的键查找(并行显示)。
Pau*_*ite 12
我想知道这里的查询执行是如何工作的
一般的执行模型是一个管道,其中每个迭代器一次返回一行。执行从根迭代器开始(在最左边,SELECT
在您的示例中标记)。
初始化后,根迭代器从其直接子节点请求一行,依此类推,直到找到可以返回行的迭代器。这会将链向上传递到根,在那里它排队等待发送到客户端。这是一个非常简化的概述,有关更多详细信息,请参见:
它是否会获取与“col2=val2”条件匹配的所有行并检查其他条件?
非聚集索引查找将定位匹配的行col2=val2
。它将能够返回col2和col1(请参阅其输出列表),因为col1存在于索引中(因为在这种情况下主键是聚集的)。
该行向上传递给嵌套循环连接,然后将控制传递给键查找。查找使用col1值搜索聚集索引 b 树以查找该行中col3的值。该值根据谓词进行测试col3=val3
,只有在匹配时才返回。
如果匹配,则行 (c1, c2, c3) 沿链向上传递并排队等待传输到客户端。当控制再次下降树时,非聚集索引中col2 的任何新匹配都将导致重复嵌套循环连接 -> 查找 -> 返回行循环。一旦非聚集索引查找用完行,当控制下一个返回到根迭代器时,该过程就完成了。
为什么这两个 -Index seek 和 Key-Lookup,在执行计划中是并行显示的?
这就是图形计划的布局方式。有关详细了解执行过程的正确方法,请参阅上面的链接和讨论。
考虑到大型数据集并假设 'col2' 中的几乎所有条目都是唯一的,它是否总是使用 'col2' 上的可用索引?
很可能是的。优化器在可用策略之间做出基于成本的选择。由于预期的匹配很少,优化器通常会将使用查找的非聚集索引搜索评估为最便宜的选项。当表非常小时会发生异常。在这种情况下,扫描聚集索引并将两个谓词应用于每一行可能看起来最便宜。
最后一点,可以避免查找的覆盖非聚集索引是:
CREATE [UNIQUE] NONCLUSTERED INDEX [dbo.table1 col2,col3 (col1)]
ON dbo.table1 (col2, col3)
INCLUDE (col1);
Run Code Online (Sandbox Code Playgroud)
UNIQUE
如果 (col2, col3) 为真,则应指定它。