有下面这样一种SQL写法,关联条件里面有or:
其中 demo101_t1(以下简称t1)和demo101_t2(以下简称t2)都是大表(几千万以上记录), 两表关联字段上重复值都比较少,如果t2表上不创建合适的索引..., 这个SQL的执行效率将会是极差的(t2表做几千万次的全表扫描,估计要执行几天吧),执行计划是这样的:
如果在t2表上分别创建object_id和object_name两个单字段索引, 效率会提升很多...一般的or改写, 都是建议使用union all, 但是很多人怕使用union all不好处理重复记录(有些记录可能会同时满足union all的上下两部分的条件,产生重复), 要做到等价需要再加点条件...;
而如果是用union, 如果不使用rowid或主键,对于本来就可能需要正常返回的重复记录, 做了去重处理, 还会丢记录, 效率比union all要低, 而且还造成了不等价....老虎刘的改写尝试:
根据oracle的一贯做法,or的改写是 union all配合lnnvl:
写法等价, 但是很遗憾, oracle的优化器在这里好像脑子短路了, 这种写法得到的执行计划,不是我们想要的