ORACLE sql tuning

问题语句:
select  TDATETIME,CONTRACTID,CONTRACTNAME,LASTPX,HIGHPX,LOWPX,CQ,TQ,LASTQTY,INITOPENINTS,OPENINTS,INTSCHG,TURNOVER,RISELIMIT,FALLLIMIT,PRESETTLE,PRECLOSE,S1,B1,SV1,BV1,OPENPX,CLOSEPX,SETTLEMENTPX,LIFELOW,LIFEHIGH,AVGPX,BIDIMPLYQTY,ASKIMPLYQTY,SIDE,MFLXID,S5,S4,S3,S2,B2,B3,B4,B5,SV5,SV4,SV3,SV2,BV2,BV3,BV4,BV5,PREDELTA,CURRDELTA,LOCALTIME,MARKET,DOMICONT,CHG,CHGPCT,VARIETIES
from GTA_QIP.MFL1_TAQ_201008
where contractid in ('l1008', 'm1008', 'p1008','y1008') order by tdatetime;
统计报告:
统计信息
----------------------------------------------------------
       1441  recursive calls
          0  db block gets
     654097  consistent gets
     637232  physical reads
          0  redo size
     311191  bytes sent via SQL*Net to client
       5684  bytes received via SQL*Net from client
        487  SQL*Net roundtrips to/from client
          7  sorts (memory)
          0  sorts (disk)
       7283  rows processed

SQL>
可以看出这个一致读和物理读高到吓死人。

问题现状:在IN里有三个条件的时候就会走索引, 有四个条件的时候就不会走索引。

最初给开发人员提示加 hints:
select  /*+INDEX(MFL1_TAQ_201008 ,INDEX_MFL1_TAQ_201008)*/ TDATETIME,CONTRACTID,CONTRACTNAME,LASTPX,HIGHPX,LOWPX,CQ,TQ,LASTQTY,INITOPENINTS,OPENINTS,INTSCHG,TURNOVER,RISELIMIT,FALLLIMIT,PRESETTLE,PRECLOSE,S1,B1,SV1,BV1,OPENPX,CLOSEPX,SETTLEMENTPX,LIFELOW,LIFEHIGH,AVGPX,BIDIMPLYQTY,ASKIMPLYQTY,SIDE,MFLXID,S5,S4,S3,S2,B2,B3,B4,B5,SV5,SV4,SV3,SV2,BV2,BV3,BV4,BV5,PREDELTA,CURRDELTA,LOCALTIME,MARKET,DOMICONT,CHG,CHGPCT,VARIETIES
from GTA_QIP.MFL1_TAQ_201008
where contractid in ('l1008', 'm1008', 'p1008','y1008') order by tdatetime;
统计报告:
统计信息
----------------------------------------------------------
          1  recursive calls
          0  db block gets
       7047  consistent gets
          1  physical reads
          0  redo size
     310871  bytes sent via SQL*Net to client
       5684  bytes received via SQL*Net from client
        487  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
       7283  rows processed


可发现速度有明显提高,从几分钟缩到几秒钟。 但存储过程中这个表名是不停变化的, 光靠加HINTS是不太可能的了。

提问: 为了加了一个条件就不会熟索引呢?
分析原因:
1. 统计不是最新的,所以CBO才不走索引。
2. 走INDEX的COST比FULL TABLE SCAN还大, 所以没有走索引。
3. OPTIMIZER_INDEX_COST_ADJ参数是不是设置的。(index 和FULL TABLE的COST的比例)
4. ORACLE 内部缺陷。
5. 看看COLUMN的分布是不是均匀。如果不均匀就收集下直方图。

当时一看到ORACLE 的版本是10G的, 心中大喜, 10G有一个功能叫AUTO_SQL_TUNING。
解决方法:
   declare
  my_task_name varchar2(30);
  mysqltext clob;
  begin
  mysqltext:='SELECT    TDATETIME,CONTRACTID,CONTRACTNAME,LASTPX,HIGHPX,LOWPX,CQ,TQ,LASTQTY,INITOPENINTS,OPENINTS,INTSCHG,TURNOVER,RISELIMIT,FALLLIMIT,PRESETTLE,PRECLOSE,S1,B1,SV1,BV1,OPENPX,CLOSEPX,SETTLEMENTPX,LIFELOW,LIFEHIGH,AVGPX,BIDIMPLYQTY,ASKIMPLYQTY,SIDE,MFLXID,S5,S4,S3,S2,B2,B3,B4,B5,SV5,SV4,SV3,SV2,BV2,BV3,BV4,BV5,PREDELTA,CURRDELTA,LOCALTIME,MARKET,DOMICONT,CHG,CHGPCT,VARIETIES
from GTA_QIP.MFL1_TAQ_201008
where contractid in (''l1008'', ''m1008'', ''p1008'',''y1008'') order by tdatetime';
  my_task_name:=dbms_sqltune.create_tuning_task
  (sql_text=>mysqltext,
  user_name=>'SYS',
  scope=>'COMPREHENSIVE',
  task_name=>'sql_tuning_test'
  );
  end;

BEGIN
     dbms_sqltune.execute_tuning_task('sql_tuning_test');
          --dbms_sqltune.drop_tuning_task('sql_tuning_test');
     END;

SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK('sql_tuning_test') FROM DUAL;
 SQL>   SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK('sql_tuning_test') FROM DUAL;
 
DBMS_SQLTUNE.REPORT_TUNING_TAS
--------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name                  : sql_tuning_test
Tuning Task Owner                 : SYS
Scope                             : COMPREHENSIVE
Time Limit(seconds)               : 1800
Completion Status                 : COMPLETED
Started at                        : 05/25/2012 17:09:41
Completed at                      : 05/25/2012 17:10:52
Number of SQL Profile Findings    : 1
 
-------------------------------------------------------------------------------
Schema Name: SYS
SQL ID     : c3vt7arcnc8p8
SQL Text   : SELECT    TDATETIME,CONTRACTID,CONTRACTNAME,LASTPX,HIGHPX,LOWPX,C
             Q,TQ,LASTQTY,INITOPENINTS,OPENINTS,INTSCHG,TURNOVER,RISELIMIT,FAL
             LLIMIT,PRESETTLE,PRECLOSE,S1,B1,SV1,BV1,OPENPX,CLOSEPX,SETTLEMENT
             PX,LIFELOW,LIFEHIGH,AVGPX,BIDIMPLYQTY,ASKIMPLYQTY,SIDE,MFLXID,S5,
             S4,S3,S2,B2,B3,B4,B5,SV5,SV4,SV3,SV2,BV2,BV3,BV4,BV5,PREDELTA,CUR
             RDELTA,LOCALTIME,MARKET,DOMICONT,CHG,CHGPCT,VARIETIES
             from GTA_QIP.MFL1_TAQ_201008
             where contractid in ('l1008', 'm1008', 'p1008','y1008') order by
             tdatetime
 
-------------------------------------------------------------------------------
FINDINGS SECTION (1 finding)
-------------------------------------------------------------------------------
 
1- SQL Profile Finding (see explain plans section below)
--------------------------------------------------------
  为此语句找到了性能更好的执行计划。
 
  Recommendation (estimated benefit: 97.78%)
  ------------------------------------------
  - 考虑接受推荐的 SQL 概要文件。
   execute dbms_sqltune.accept_sql_profile(task_name => 'sql_tuning_test',
            replace => TRUE);
 
-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------
 
1- Original With Adjusted Cost
------------------------------
Plan hash value: 2802143541
 
--------------------------------------------------------------------------------
| Id  | Operation          | Name            | Rows  | Bytes |TempSpc| Cost (%CP
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                 |  3269 |   648K|       |   143K  (
|   1 |  SORT ORDER BY     |                 |  3269 |   648K|  1056K|   143K  (
|*  2 |   TABLE ACCESS FULL| MFL1_TAQ_201008 |  3269 |   648K|       |   143K  (
--------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - filter("CONTRACTID"='l1008' OR "CONTRACTID"='m1008' OR "CONTRACTID"='p100
              "CONTRACTID"='y1008')
 
2- Using SQL Profile
--------------------
Plan hash value: 1571978519
 
--------------------------------------------------------------------------------
| Id  | Operation                     | Name                  | Rows  | Bytes |T
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |                       |  3269 |   648K|
|   1 |  SORT ORDER BY                |                       |  3269 |   648K|
|   2 |   INLIST ITERATOR             |                       |       |       |
|   3 |    TABLE ACCESS BY INDEX ROWID| MFL1_TAQ_201008       |  3269 |   648K|
|*  4 |     INDEX RANGE SCAN          | INDEX_MFL1_TAQ_201008 |  7282 |       |
--------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   4 - access("CONTRACTID"='l1008' OR "CONTRACTID"='m1008' OR "CONTRACTID"='p100
              "CONTRACTID"='y1008')
 
-------------------------------------------------------------------------------

从以上报告可以得出,ORACLE建议执行以下语句:
execute dbms_sqltune.accept_sql_profile(task_name => 'sql_tuning_test',
            replace => TRUE);
然后再执行查询就可以发现查询走索引了,速度也优化到了2秒钟。    但遗憾的是最终问题还是没有解决, 表名是动态的,有一百多张表,总不可能每张表都这样做一次吧,望高人能够给些建议。

小知识:
查询表统计时间:dba_tables中的Last analyst 字段。
动态HINTS(高人提到的, 不解, 查不到相关的东西,请高人指点。):  
 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22740983/viewspace-734641/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/22740983/viewspace-734641/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值