如何加快查询速度?

时间:2015-08-05 16:06:09

标签: sql oracle performance query-optimization

如何加快此查询?

 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 ); 

2 个答案:

答案 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

我会探索其他选择,但没有更多信息,我可以提供。