优化SQL的另类思考

 

  
  
  
  
  1. 今天给大家介绍一个SQL优化案例,这是statpack中逻辑读排名第一的SQL.当前创建的索引建在(username,ends,approve_status,promoted_status)上。 
  2.   
  3.  
  4. Buffer Gets    Executions  Gets per Exec  %Total Time (s)  Time (s) Hash Value 
  5. ------------- ------------ -------------- ------ -------- --------- ---------- 
  6. 116,608,373      164,083          710.7   40.6  7027.07  11922.30 3701069644 
  7. Module: [email protected] (TNS V1-V3) 
  8.            select count(*)           from test 
  9.    where  username = :1    --这是一个高势列, 
  10.    and    ends>sysdate 
  11.    and approve_status in (0,1,-9) 
  12.    and id <> :2            --这是主键 
  13.    and promoted_status = 1 
  14.  
  15. 如果大家见到这样的SQL语句会怎么样优化?通常的做法,是在当前索引中冗余id字段,以避免回表。但这样要去调整这张大表的索引. 
  16.  
  17. 在看到上面的SQL后,询问开发能否明确的知道id=:2并且满足其它条件的这样的记录是否一定存在。开发经过查证后,最后的答复是无法肯定.既然在应用层无法确定,那也要想个办法来解决大量回表的问题。在经过仔细观察后,我将上面这条SQL语句转换成下面两条SQL以及最后一步应用逻辑来实现: 
  18.  
  19. 第一条SQL: 
  20. Select/*+ index(a, PK_test_ID) */ count(*)   from test a 
  21.    where id=:1 and  ends>sysdate and approve_status in (0,1,-9)  and promoted_status = 1 and username=:2 
  22.  
  23. 第二条SQL: 
  24. select count(*)    from test 
  25.    where  username = :1 and     ends>sysdate and approve_status in (0,1,-9) and     and promoted_status = 1 
  26.  
  27. 第三步,将两个结果相减即可实现业务 
  28.  
  29. 我们在做SQL优化时,如何把一条SQL根据需要等价转化成多条,需要考虑当前的应用逻辑,以及当前数据库中索引的情况,优化便会事半功倍。如何跳出ORACLE去思考问题,希望这个优化案例能对大家有所启示。 

 

你可能感兴趣的:(sql,数据库,职场,优化SQL,休闲)