我有两个表 tb1 和 tb2,tb1 上没有任何索引。我用 1000000 行填充了 tb1,tb2 中有 500 行,并且在 ID 列上有一个聚集索引。
为了理解嵌套循环连接,我使用了以下查询:
SELECT *
FROM tb1
INNER JOIN tb2 ON tb1.id=tb2.id
OPTION(loop join);
为此,我得到了以下执行计划:
扫描没有索引的 Tb1,成本为 2%,而在 tb2 上使用索引,成本为 98%。
我的问题是:
- 如何理解上述片段 (138.236) 显示的估计运营商成本
- 从上面的表扫描片段(成本为2%)来看,执行次数为24,这是否意味着sql批量读取存储在内存中的行,并且对于每一行它都从tbl2中进行查找操作?
有人可以向我解释一下执行计划以及任何有关强制扫描、单击操作员后按 F4 时强制索引的更多信息的指针。
堆表只全扫描一次,索引查找却执行了1,000,000次。优化器估计,在这种情况下,一百万次查找将占执行查询总成本的 98.4%,而堆表的单个并行扫描将占成本的 0.9%。
这些只是用于内部计划选择原因的估计;它们通常不会反映现代硬件上的真实性能,而且永远只是估计 - 即使在执行后(“实际”)执行计划中也是如此。
在管理工作室:
在SQL Sentry 计划资源管理器中:
不,这意味着 24 个并行线程合作执行堆表的单次扫描。每个线程仍然一次从扫描中读取一行,对索引表执行查找,然后从扫描中获取下一行,依此类推,直到任务完成。
在这个计划中,行没有被批量读取并存储在内存中。SQL Server 报告 24 次扫描,因为 24 个线程各自执行了表的部分扫描,导致整体扫描一次。
如果查询指定了、或提示,或者如果查询优化器决定正确性需要特定的访问策略(例如,检查外键约束时)
ForceScan
,则ForceSeek
、 和ForcedIndex
属性将设置为 true 。FORCESCAN
FORCESEEK
INDEX