通过改写SQL来优化性能, 如何做?

    网友说这个SQL语句跑了两上小时, 没有什么思路去解决.

select tbilltrace_43.bno,tbilltrace_43.SAVETIMESTAMP
from
   ( select bno,SAVETIMESTAMP
     from tbilltrace
     where  SAVETIMESTAMP>=monitor_start_date
       and SAVETIMESTAMP<=monitor_end_date and opcode=43
   ) tbilltrace_43
where not exists
(select bno
   from ( select bno from tbilltrace
          where SAVETIMESTAMP>=monitor_start_date  
            and SAVETIMESTAMP<=monitor_end_date and opcode=50
          union all
          select bno from tbilltrace
          where SAVETIMESTAMP>=monitor_start_date
            and SAVETIMESTAMP<=monitor_end_date and opcode=51
        ) tbilltrace_51_50
where tbilltrace_51_50.bno=tbilltrace_43.bno);  

    SQL语句的性能和数据量有关, 首先需要知道第一个子查询会返回多少条记录, 其次中间的那个UNION ALL应当折开成两个Not Exists, 我认为在opcode或SAVETIMESTAMP列上的索引应当不是很有效的, 而bno列上的索引应当是很有效的. 因此改写后的SQL应当如下:

select bno,SAVETIMESTAMP
     from tbilltrace tbilltrace_43
     where  SAVETIMESTAMP>=monitor_start_date
       and SAVETIMESTAMP<=monitor_end_date and opcode=43
where not exists
  (select 1 from tbilltrace tbilltrace_50
          where SAVETIMESTAMP>=monitor_start_date  
            and SAVETIMESTAMP<=monitor_end_date and opcode=50
            and bno = tbilltrace_43.bno)
  and not exists
  (select 1 from tbilltrace tbilltrace_51
          where SAVETIMESTAMP>=monitor_start_date  
            and SAVETIMESTAMP<=monitor_end_date and opcode=51
            and bno = tbilltrace_43.bno)

    如果不考虑空间的情况, 则建以下的两个索引:

Index 1 (opcode, savetimestamp, bno)
Index 2 (bno, opcode, savetimestamp)

    这样的Tuning其实很简单的.

留言 (3)

首先是 弄清楚 数据分布 和 你的目标.

and always ask why .

数据分布和要得到什么数据,不断改进方法,哈哈

dcba东西真多,每天都由新文章

发表留言:

« Previous | Main | Next »

英语900句 | English 900

  • You'd better put on your jacket. It's cold outside.
  • 你最好穿上夹克, 外面冷.
  • The blouse no longer fits me.
  • 这件衬衣不再合我身了.
  • My son has outgrown these trousers.
  • 我儿子已经长的穿不了这条裤子了.
  • The shoes are worn-out.
  • 这鞋已经不能穿了.
  • I don't like wearing the uniform.
  • 我不喜欢穿制服.