INSERT INTO t4 VALUES (1,2,'aa1'),(2,1,'bb1'),(2,3,'cc1'),(3,3,'cc1'),(4,2,'ff1'),(4,4,'ert'),(4,2,'f5fg'),(null,2,'ee'),(5,30,'cc1'),(5,4,'fcc1'),(4,10,'cc1'),(6,4,'ccd1'),(null,1,'fee'),(1,2,'aa1'),(2,1,'bb1'),(2,3,'cc1'),(3,3,'cc1'),(4,2,'ff1'),(4,4,'ert'),(4,2,'f5fg'),(null,2,'ee'),(5,30,'cc1'),(5,4,'fcc1'),(4,10,'cc1'),(6,4,'ccd1'),(null,1,'fee'),(1,2,'aa1'),(2,1,'bb1'),(2,3,'cc1'),(3,3,'cc1'),(4,2,'ff1'),(4,4,'ert'),(4,2,'f5fg'),(null,2,'ee'),(5,30,'cc1'),(5,4,'fcc1'),(4,10,'cc1'),(6,4,'ccd1'),(null,1,'fee');
以上例子因为condition_fanout_filter的设置不同而导致选择了不同的驱动表,最后的扫描行为也不一样。但是明显先实行t3的索引范围扫描比t4的全表扫描服从高,因此这个例子可以看出condition_fanout_filter的预估过滤百分比有更多主观性,最终可能导致错误的优化路径。
附表:join_type访问方法的范例
join_type访问方法的范例说明JT_UNKNOWN无效JT_SYSTEM表只有一行,比如select * from (select 1)JT_CONST表最多只有一行满意,比如WHERE table.pk = 3JT_EQ_REF=符号用在唯一索引JT_REF=符号用在非唯一索引JT_ALL全表扫描JT_RANGE范围扫描JT_INDEX_SCAN索引扫描JT_FTFulltext索引扫描JT_REF_OR_NULL包含null值,比如"WHERE col = ... OR col IS NULLJT_INDEX_MERGE一张表实行多次范围扫描最后合并效果
以上各类扫描方式由快到慢排序为:system > const > eq_ref > ref > range > index > ALL
二、不关condition_fanout_filter的解决办法
如果不关闭condition_fanout_filter有没有办法逼迫指定毗连顺序呢?答案是有的。一共如下3个方法,可以按照自己的需要举行灵活操作。
1、使用 qb_name 提示词来指定毗连顺序
[code]greatsql> EXPLAIN SELECT /*+ qb_name(qb1) JOIN_ORDER(@qb1 t3,t4) */ * FROM t4 join t3 ON t4.d1=t3.ccc1 and t4.d2=t3.ccc2 where t4.d1 CREATE INDEX idx4_1 ON t4(d1);greatsql> EXPLAIN SELECT * FROM t4 join t3 ON t4.d1=t3.ccc1 and t4.d2=t3.ccc2 where t4.d1 EXPLAIN SELECT /*+ qb_name(qb1) JOIN_FIXED_ORDER(@qb1) */ * FROM t3 join t4 ON t4.d1=t3.ccc1 AND t4.d2=t3.ccc2 WHERE t4.d1