如何加快此查询?
l_string varchar2(200);
/* parameter string */
l_string := ':27.07.2015:10.07.2015:23.07.2015:01.08.2015:';
select t3.*
from table1 t1, table2 t2, table3 t3
where t1.col1 = t2.col2
and t2.col3 = t3.col4
and (instr(l_string, ':' || to_char(t3.col1, 'dd.mm.yyyy') || ':') > 0 OR
instr(l_string, ':' || to_char(t3.col2, 'dd.mm.yyyy') || ':') > 0 OR
instr(l_string, ':' || to_char(t3.col3, 'dd.mm.yyyy') || ':') > 0 OR
instr(l_string, ':' || to_char(t3.col4, 'dd.mm.yyyy') || ':') > 0 OR
instr(l_string, ':' || to_char(t3.col5, 'dd.mm.yyyy') || ':') > 0 OR
instr(l_string, ':' || to_char(t3.col6, 'dd.mm.yyyy') || ':') > 0 OR
instr(l_string, ':' || to_char(t3.col7, 'dd.mm.yyyy') || ':') > 0 OR
instr(l_string, ':' || to_char(t3.col8, 'dd.mm.yyyy') || ':') > 0 OR
instr(l_string, ':' || to_char(t3.col9, 'dd.mm.yyyy') || ':') > 0 );
答案 0 :(得分:1)
您使用instr的谓词不允许索引访问。所以你要以T3的全表扫描结束。 您可以将谓词不同地表述为:
where col1 in (to_date('27.07.2015','dd.mm.yyyy'),
to_date('10.07.2015','dd.mm.yyyy'),
to_date('23.07.2015','dd.mm.yyyy'),
to_date('01.08.2015','dd.mm.yyyy')) or
col2 in (to_date('27.07.2015','dd.mm.yyyy'),
to_date('10.07.2015','dd.mm.yyyy'),
to_date('23.07.2015','dd.mm.yyyy'),
to_date('01.08.2015','dd.mm.yyyy')) or
col3 in (to_date('27.07.2015','dd.mm.yyyy'),
to_date('10.07.2015','dd.mm.yyyy'),
to_date('23.07.2015','dd.mm.yyyy'),
to_date('01.08.2015','dd.mm.yyyy')) or
.... -- etc for columns col3 - col9
如果表T3很大且上面的谓词只选择了几条记录,那么你可以通过定义col1到col9的索引来获利
create index t3_ix1 on t3(col1);
create index t3_ix2 on t3(col2);
....
可能的执行计划将执行9 * 3(列*值)INDEX RANGE SCAN和BITMAP CONVERSION以获得OR结果。因此,对于真正的巨大T3,27指数范围扫描将更好,全面扫描,你将加速;但这取决于你的数据...
答案 1 :(得分:0)
我没有要测试的Oracle实例,但OR
条件几乎总是减慢执行速度,多次调用instr
。尝试进行一次大型连接并在那里搜索值。你会注意到我添加了一个'〜'以确保你没有得到数据匹配的结果:
select t3.*
from table1 t1, table2 t2, table3 t3
where t1.col1 = t2.col2
and t2.col3 = t3.col4
and instr(l_string,
(':' || to_char(t3.col1, 'dd.mm.yyyy') || ':' ||
'~:' || to_char(t3.col2, 'dd.mm.yyyy') || ':' ||
'~:' || to_char(t3.col3, 'dd.mm.yyyy') || ':' ||
'~:' || to_char(t3.col4, 'dd.mm.yyyy') || ':' ||
'~:' || to_char(t3.col5, 'dd.mm.yyyy') || ':' ||
'~:' || to_char(t3.col6, 'dd.mm.yyyy') || ':' ||
'~:' || to_char(t3.col7, 'dd.mm.yyyy') || ':' ||
'~:' || to_char(t3.col8, 'dd.mm.yyyy') || ':' ||
'~:' || to_char(t3.col9, 'dd.mm.yyyy') || ':') > 0
我会探索其他选择,但没有更多信息,我可以提供。