概述
估算出每个候选访问计划执行的以下指标:
基于规则的估算选取候选访问计划
- 索引的选择率 < 0.1(即索引过滤剩下的记录个数为集合记录个数的 10%)
- 索引完全匹配排序字段及排序方向
- 全表扫描
- 符合指标 1 的候选访问计划,再基于代价的进行估算,最终选出总代价最小的访问计划执行查询。
示例
集合 foo.bar 上的有索引:
- “index_a” :
- “index_b” :
{ b : 1 }
- “index_c” :
查询 db.foo.bar.find( { a : 1, b : 2 } ).sort( { c : 1 } )
可以有以下的访问计划:
- IXSCAN( “index_b” ) ==> SORT( { c : 1 } )
- IXSCAN( “index_c” )
- TBSCAN() ==> SORT( { c : 1 } )
然后通过代价估算确定总代价最小的访问计划,并选取执行查询。假设估算出 4 个候选访问计划的总代价分别为 1000,800,12000 和 1000,则最终选择访问计划 2 执行查询。
索引选择率的估算有两种方式:
- 使用统计信息进行估算
- 使用默认值进行估算
使用默认值进行估算:
数值
- 在 的区间中选取
- 如
{ $lt : 0 }
的选择率为:
字符串
- 逐个字符计算在 ‘ ‘ (空格 ASCII 码:32)至 ASCII 码 127 之间的比例
-
- 相等比较:0.005
- 大于、小于比较:0.333333
- 范围比较:0.05
访问计划的搜索过程
使用 SdbQuery.explain() 可以查看查询的访问计划。
当 SdbQuery.explain() 的 Search 选项为 true 时,将会展示查询优化器搜索过的访问计划,并查看查询优化器选择的结果。 当 SdbQuery.explain() 的 Evaluate 选项为 true 时,将会展示查询优化器估算访问计划的总代价的演算过程。
Note:
- 搜索过的访问计划不在访问计划缓存中,因此 Search 选项不使用缓存,重新估算
- 搜索过程将嵌套展示在数据节点每个集合的访问计划中