分别执行两条语句,它们之间仅仅adminaccount条件不同,一个是admin,一个是lgm。
为什么用时差距这么大,而且条件为admin的语句符合的记录多,用时少。而条件为lgm的语句符合的记录少,用时多。
select art.article_id,art.article_title,aps.adminaccount from cmsarticle art,powerscope aps where art.column_id=aps.scopestr  and    aps.funcnodepath ='A001' and    aps.adminaccount='lgm';
执行这条语句后有1795条符合,用时0.531秒执行计划如下:
PLAN_TABLE_OUTPUT 
1 Plan hash value: 3857331516 
2   
3 ------------------------------------------------------------------------------------------- 
4 | Id  | Operation          | Name                 | Rows  | Bytes | Cost (%CPU)| Time     | 
5 ------------------------------------------------------------------------------------------- 
6 |   0 | SELECT STATEMENT   |                      | 44229 |  3196K|  4344   (1)| 00:00:53 | 
7 |*  1 |  HASH JOIN         |                      | 44229 |  3196K|  4344   (1)| 00:00:53 | 
8 |*  2 |   TABLE ACCESS FULL| TBNC_ADMINPOWERSCOPE |   541 | 16230 |    56   (2)| 00:00:01 | 
9 |   3 |   TABLE ACCESS FULL| TBNC_CMSARTICLE      | 40782 |  1752K|  4288   (1)| 00:00:52 | 
10 ------------------------------------------------------------------------------------------- 
11   
12 Predicate Information (identified by operation id): 
13 --------------------------------------------------- 
14   
15    1 - access("APS"."SCOPESTR"=TO_NUMBER("ART"."COLUMN_ID")) 
16    2 - filter("APS"."ADMINACCOUNT"='admin_two' AND  
17               "APS"."FUNCNODEPATH"='A001') 
-----------------------------------------------------------
select art.article_id,art.article_title,aps.adminaccount from cmsarticle art,powerscope aps where art.column_id=aps.scopestr  and    aps.funcnodepath ='A001' and    aps.adminaccount='admin';
执行这条语句后有148条符合,用时3.906秒执行计划如下:
PLAN_TABLE_OUTPUT 
1 Plan hash value: 2231333241 
2   
3 ----------------------------------------------------------------------------------------------------- 
4 | Id  | Operation                    | Name                 | Rows  | Bytes | Cost (%CPU)| Time     | 
5 ----------------------------------------------------------------------------------------------------- 
6 |   0 | SELECT STATEMENT             |                      |   888 | 65712 |  4291   (1)| 00:00:52 | 
7 |*  1 |  HASH JOIN                   |                      |   888 | 65712 |  4291   (1)| 00:00:52 | 
8 |*  2 |   TABLE ACCESS BY INDEX ROWID| TBNC_ADMINPOWERSCOPE |    11 |   330 |     3   (0)| 00:00:01 | 
9 |*  3 |    INDEX RANGE SCAN          | SYS_LGM              |    87 |       |     1   (0)| 00:00:01 | 
10 |   4 |   TABLE ACCESS FULL          | TBNC_CMSARTICLE      | 40782 |  1752K|  4288   (1)| 00:00:52 | 
11 ----------------------------------------------------------------------------------------------------- 
12   
13 Predicate Information (identified by operation id): 
14 --------------------------------------------------- 
15   
16    1 - access("APS"."SCOPESTR"=TO_NUMBER("ART"."COLUMN_ID")) 
17    2 - filter("APS"."FUNCNODEPATH"='A001') 
18    3 - access("APS"."ADMINACCOUNT"='lgm') 
-------------------------------------------------------

解决方案 »

  1.   

    admine有索引
    另外一个没索引
      

  2.   

     2  ¦   TABLE ACCESS FULL ¦ TBNC_ADMINPOWERSCOPE  ¦   541  ¦ 16230  ¦    56   (2) ¦ 00:00:01  ¦  
    这个执行计划是全表扫描而另一个
    8  ¦*  2  ¦   TABLE ACCESS BY INDEX ROWID ¦ TBNC_ADMINPOWERSCOPE  ¦    11  ¦   330  ¦     3   (0) ¦ 00:00:01  ¦ 
    用的是索引
      

  3.   

    admin仅仅是powerscope表中字段adminaccount的一个值而已,lgm也是powerscope表中字段adminaccount的一个值。难道是对某一具体值索引吗?
      

  4.   

    在TBNC_ADMINPOWERSCOPE  表中有两个索引一个是TBNC_ADMINPOWERSCOPE  表的ID,一个是adminaccount,但奇怪的是为什么当adminaccoun='lgm'的时候用到adminaccount索引,而当adminaccount='admin_two'的时候却没有用到adminaccount索引,更为奇怪的是用到adminaccount索引的执行计划只是在adminaccount='lgm'的执行计划中出现,而且它的速度还慢。
      

  5.   

    select art.article_id,art.article_title,aps.adminaccount from cmsarticle art,powerscope aps where art.column_id=aps.scopestr  and    aps.funcnodepath ='A001' and    aps.adminaccount='lgm'; 
    执行这条语句后有1795条符合,用时0.531秒 执行计划如下: 16    2 - filter("APS"."ADMINACCOUNT"='admin_two' AND   
    17               "APS"."FUNCNODEPATH"='A001')  
    ----------------------------------------------------------- 
    select art.article_id,art.article_title,aps.adminaccount from cmsarticle art,powerscope aps where art.column_id=aps.scopestr  and    aps.funcnodepath ='A001' and    aps.adminaccount='admin'; 
    执行这条语句后有148条符合,用时3.906秒 执行计划如下: 
    PLAN_TABLE_OUTPUT  18    3 - access("APS"."ADMINACCOUNT"='lgm')  
    ------------------------------------------------------- 是不是两个语句的执行计划贴错了。 下面的执行计划是上面sql的。上面的执行计划应该不属于这两个sql
      

  6.   

    谢谢楼上的朋友,时我写错了。第一个SQL是admin_two,第二个SQL是lgm
      

  7.   

    我是通过在PLSQL Developer里统计的,而且可以明显感觉到速度差异大的问题
      

  8.   


    执行计划选择的选择会和数据有关系,从因为Oracle是基于成本的优化方案,
    所以有数据的采样率会影响执行计划的选择,
    我做一个假设:
    假设我们有一个表,叫TableA,它有三个字段分别是ColA,ColB,ColC,表没有主键,所有字段都非空。
    ColB值只能是('sys','user','costomer')这三种的其中一种,数据表中有一万记录。
    数据的分布分别是(2%,95%,3%)
    再假设,我们在ColB上有一个B树索引。如果我们写这样的Sql:
    SELECT *
      FROM TableA
     where ColB = 'user'你说上面的SQL一定会使用在ColB上的索引吗?
    结果是根据统计做出分析,执行计划会随着数据变化而变化。
    以上SQL多数时候是不使用索引的,因为Select字段的*影响了执行计划,
    假设Oralce通过索引进行快速扫描,那么它会执行9500次检索,但为了
    取得ColA和ColC它不的不在通过 Rowid获取数据,获取数据需要9500次,
    这样Oracle 就需要 19000次操作才能完成工作。但是要是使用全表扫描只需要1万次就可以搞定了,
    所以这时候Oracle会选择全表扫描。
    如果我们现在改造一下:
    SELECT ColB 
      FROM TableA
     where ColB = 'user'可以肯定的说,Oracle一定会使用索引。不知道这样解释对你有帮助没有,现在在上班,所以写的仓促了些,
    多多包涵,不明白请提问。
      

  9.   

    在绝大多数Oracle可以自己维护统计信息,
    但是特殊的时候需要人工接入,很多时候你会听到,
    DBA抱怨,原来的SQL运行的很好,但是执行完统计后,
    SQL变的超级慢之类的话题,SQL没有改变,但是统计信息发生了变化,
    直接影响执行计划。在特定的环境下,全表扫描回比索引执行的快,这是正常的。
      

  10.   

    给你个思考题,嘿嘿:SELECT *
      FROM TableA 
     where ColB = 'sys' 你说是全表扫描快还是索引扫描快?