如何加快查询速度?

How can I speed up the query?

我怎样才能加快这个查询?

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

我没有要测试的 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

我会探索其他选择,但没有更多信息,我只能提供这些。

您使用 instr 的谓词不允许索引访问。因此,您将以 T3 的完整 table 扫描结束。 您可以将谓词表述为不同的形式:

 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

如果 table 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 索引范围扫描会比 FULL SCAN 更好,你会加速;但这取决于您的数据...