Oracle 10g的隐含参数_complex_view_merging引发的性能问题

今天在Oracle 10g上碰到一个奇怪的问题,有一条sql在数据库1上很快,在数据库2上很慢,数据库2的数据是从数据库1上导的,数据量差不多。

在数据库1上执行0.01s。

SQL> SELECT A.*,
  2        B.INCREASE_ID,
  3        B.TRANSACTION_ID,
  4        B.LINK_CARD_ID,
  5        B.VALIDATE_FLAG,
  6        B.ASSET_VALUE_SHARING,
  7        B.RELATED_DEVICE_ID,
  8        B.PARENT_CARD_CODE,
  9        B.PROJECT_VALUE,
 10        B.DELETE_FLAG,
 11        B.DEPRECIATION_ADJUST_VALUE,
 12        T.TRANSACTION_MODE_CODE,
 13        T.TRANSACTION_NO,
 14        T.TRANSACTION_FROM,
 15        T.FROM_MODEL,
 16        (SELECT T.FULL_PATH
 17            FROM AM_TECH_OBJECT_NODE_0900 T
 18          WHERE T.TECH_OBJECT_ID = A.DEVICE_ID
 19            AND T.NODE_TYPE = 2
 20            AND ROWNUM = 1) AS FULL_PATH,
 21        AAC.FULL_NAME CLASSIFY_FULL_PATH
 22    FROM V_ASSET_CARD_0900      A,
 23        GG_ASSET_INCREASE_ITEM B,
 24        GG_ASSET_TRANSACTION  T,
 25        AM_ASSET_CLASSIFY      AAC
 26  WHERE A.CARD_ID = B.CARD_ID
 27    AND B.TRANSACTION_ID = T.TRANSACTION_ID
 28    AND A.CLASSIFY_ID = AAC.DEVICE_CLASSIFY_ID(+)
 29    AND B.TRANSACTION_ID = '0101109514';
已用时间:  00: 00: 00.01
执行计划
----------------------------------------------------------
Plan hash value: 3643758043
-------------------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name                          | Rows  | Bytes | Cost (%CPU)| Time    |
-------------------------------------------------------------------------------------------------------------------
|  0 | SELECT STATEMENT                |                                |    21 | 24129 |  167  (0)| 00:00:03 |
|*  1 |  COUNT STOPKEY                  |                                |      |      |            |          |
|  2 |  TABLE ACCESS BY INDEX ROWID    | AM_TECH_OBJECT_NODE_0900      |    1 |    73 |    4  (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN              | IDX_TECH_NODE_ID_0900          |    1 |      |    3  (0)| 00:00:01 |
|  4 |  NESTED LOOPS OUTER              |                                |    21 | 24129 |  167  (0)| 00:00:03 |
|  5 |  NESTED LOOPS                  |                                |    21 | 22533 |  146  (0)| 00:00:02 |
|  6 |    NESTED LOOPS                  |                                |    20 | 12700 |  106  (0)| 00:00:02 |
|  7 |    NESTED LOOPS                |                                |    20 | 10900 |    46  (0)| 00:00:01 |
|  8 |      NESTED LOOPS                |                                |    20 |  2000 |    6  (0)| 00:00:01 |
|  9 |      TABLE ACCESS BY INDEX ROWID| GG_ASSET_TRANSACTION          |    1 |    42 |    2  (0)| 00:00:01 |
|* 10 |        INDEX UNIQUE SCAN        | PK_GG_ASSET_TRANSACTION        |    1 |      |    1  (0)| 00:00:01 |
|  11 |      TABLE ACCESS BY INDEX ROWID| GG_ASSET_INCREASE_ITEM        |    20 |  1160 |    4  (0)| 00:00:01 |
|* 12 |        INDEX RANGE SCAN          | TRANSACTION_DETAIL_REF_TRANSAC |    20 |      |    1  (0)| 00:00:01 |
|  13 |      TABLE ACCESS BY INDEX ROWID | GG_ASSET_CARD_0900            |    1 |  445 |    2  (0)| 00:00:01 |
|* 14 |      INDEX UNIQUE SCAN          | PK_GG_ASSET_CARD_0303          |    1 |      |    1  (0)| 00:00:01 |
|  15 |    TABLE ACCESS BY INDEX ROWID  | GG_ASSET_VALUE_0900            |    1 |    90 |    3  (0)| 00:00:01 |
|* 16 |      INDEX RANGE SCAN            | ID_FAV_CARD_VALIDITY_0303      |    1 |      |    2  (0)| 00:00:01 |
|  17 |    TABLE ACCESS BY INDEX ROWID  | AM_ASSET_0900                  |    1 |  438 |    2  (0)| 00:00:01 |
|* 18 |    INDEX UNIQUE SCAN            | PK_AM_ASSET_0900              |    1 |      |    1  (0)| 00:00:01 |
|  19 |  TABLE ACCESS BY INDEX ROWID    | AM_ASSET_CLASSIFY              |    1 |    76 |    1  (0)| 00:00:01 |
|* 20 |    INDEX UNIQUE SCAN            | PK_AM_ASSET_CLASSIFY          |    1 |      |    0  (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
  1 - filter(ROWNUM=1)
  3 - access("T"."TECH_OBJECT_ID"=:B1 AND "T"."NODE_TYPE"=2)
  10 - access("T"."TRANSACTION_ID"='0101109514')
  12 - access("B"."TRANSACTION_ID"='0101109514')
  14 - access("GG_ASSET_CARD"."CARD_ID"="B"."CARD_ID")
  16 - access("GG_ASSET_VALUE"."CARD_ID"="GG_ASSET_CARD"."CARD_ID" AND
              "GG_ASSET_VALUE"."VALIDITY_DATE_END"="GG_ASSET_CARD"."DECREASE_DATE")
  18 - access("AM_ASSET"."DEVICE_ID"="GG_ASSET_CARD"."DEVICE_ID")
  20 - access("AM_ASSET"."CLASSIFY_ID"="AAC"."DEVICE_CLASSIFY_ID"(+))
统计信息
----------------------------------------------------------
          8  recursive calls
          0  db block gets
        28  consistent gets
          0  physical reads
          0  redo size
      12384  bytes sent via SQL*Net to client
        338  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

 

 

在数据库2上很慢,27.48s
SQL> SELECT A.*,
  2        B.INCREASE_ID,
  3        B.TRANSACTION_ID,
  4        B.LINK_CARD_ID,
  5        B.VALIDATE_FLAG,
  6        B.ASSET_VALUE_SHARING,
  7        B.RELATED_DEVICE_ID,
  8        B.PARENT_CARD_CODE,
  9        B.PROJECT_VALUE,
 10        B.DELETE_FLAG,
 11        B.DEPRECIATION_ADJUST_VALUE,
 12        T.TRANSACTION_MODE_CODE,
 13        T.TRANSACTION_NO,
 14        T.TRANSACTION_FROM,
 15        T.FROM_MODEL,
 16        (SELECT T.FULL_PATH
 17            FROM AM_TECH_OBJECT_NODE_0900 T
 18          WHERE T.TECH_OBJECT_ID = A.DEVICE_ID
 19            AND T.NODE_TYPE = 2
 20            AND ROWNUM = 1) AS FULL_PATH,
 21        AAC.FULL_NAME CLASSIFY_FULL_PATH
 22    FROM V_ASSET_CARD_0900      A,
 23        GG_ASSET_INCREASE_ITEM B,
 24        GG_ASSET_TRANSACTION  T,
 25        AM_ASSET_CLASSIFY      AAC
 26  WHERE A.CARD_ID = B.CARD_ID
 27    AND B.TRANSACTION_ID = T.TRANSACTION_ID
 28    AND A.CLASSIFY_ID = AAC.DEVICE_CLASSIFY_ID(+)
 29    AND B.TRANSACTION_ID = '0101109514';
已选择200行。
已用时间:  00: 00: 27.48
执行计划
----------------------------------------------------------
Plan hash value: 2944357796
-------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name                          | Rows  | Bytes |TempSpc| Cost (%CPU)| Time    |
-------------------------------------------------------------------------------------------------------------------------
|  0 | SELECT STATEMENT              |                                |    25 |  255K|      | 45815  (1)| 00:09:10 |
|*  1 |  COUNT STOPKEY                |                                |      |      |      |        |            |
|  2 |  TABLE ACCESS BY INDEX ROWID  | AM_TECH_OBJECT_NODE_0900      |    1 |    75 |      |    4  (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN            | IDX_TECH_NODE_ID_0900          |    1 |      |      |    3  (0)| 00:00:01 |
|  4 |  NESTED LOOPS OUTER            |                                |    25 |  255K|      | 45815  (1)| 00:09:10 |
|*  5 |  HASH JOIN                    |                                |    25 |  253K|      | 45790  (1)| 00:09:10 |
|  6 |    NESTED LOOPS                |                                |    25 |  2750 |      |    6  (0)| 00:00:01 |
|  7 |    TABLE ACCESS BY INDEX ROWID| GG_ASSET_TRANSACTION          |    1 |    53 |      |    2  (0)| 00:00:01 |
|*  8 |      INDEX UNIQUE SCAN        | PK_GG_ASSET_TRANSACTION        |    1 |      |      |    1  (0)| 00:00:01 |
|  9 |    TABLE ACCESS BY INDEX ROWID| GG_ASSET_INCREASE_ITEM        |    25 |  1425 |      |    4  (0)| 00:00:01 |
|* 10 |      INDEX RANGE SCAN          | TRANSACTION_DETAIL_REF_TRANSAC |    25 |      |      |    1  (0)| 00:00:01 |
|  11 |    VIEW                        | V_ASSET_CARD_0900              |  280K|  2744M|      | 45781  (1)| 00:09:10 |
|* 12 |    HASH JOIN                  |                                |  280K|  257M|  141M| 45781  (1)| 00:09:10 |
|* 13 |      HASH JOIN                |                                |  274K|  137M|    27M| 12222  (1)| 00:02:27 |
|  14 |      TABLE ACCESS FULL        | GG_ASSET_VALUE_0900            |  292K|    24M|      |  910  (2)| 00:00:11 |
|  15 |      TABLE ACCESS FULL        | GG_ASSET_CARD_0900            |  274K|  114M|      |  4073  (1)| 00:00:49 |
|  16 |      TABLE ACCESS FULL        | AM_ASSET_0900                  |  756K|  315M|      | 10464  (1)| 00:02:06 |
|  17 |  TABLE ACCESS BY INDEX ROWID  | AM_ASSET_CLASSIFY              |    1 |    76 |      |    1  (0)| 00:00:01 |
|* 18 |    INDEX UNIQUE SCAN          | PK_AM_ASSET_CLASSIFY          |    1 |      |      |    0  (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
  1 - filter(ROWNUM=1)
  3 - access("T"."TECH_OBJECT_ID"=:B1 AND "T"."NODE_TYPE"=2)
  5 - access("A"."CARD_ID"="B"."CARD_ID")
  8 - access("T"."TRANSACTION_ID"='0101109514')
  10 - access("B"."TRANSACTION_ID"='0101109514')
  12 - access("AM_ASSET"."DEVICE_ID"="GG_ASSET_CARD"."DEVICE_ID")
  13 - access("GG_ASSET_VALUE"."CARD_ID"="GG_ASSET_CARD"."CARD_ID" AND
              "GG_ASSET_VALUE"."VALIDITY_DATE_END"="GG_ASSET_CARD"."DECREASE_DATE")
  18 - access("A"."CLASSIFY_ID"="AAC"."DEVICE_CLASSIFY_ID"(+))
统计信息
----------------------------------------------------------
        218  recursive calls
          0  db block gets
      70112  consistent gets
      26412  physical reads
        348  redo size
      38174  bytes sent via SQL*Net to client
        480  bytes received via SQL*Net from client
        15  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
        200  rows processed

第一次诊断:起初觉得应该是索引的集群因子的问题,检查了下,差不多。

第二次诊断:感觉是环境、参数不一样引起,开始试验。

使用视图v$sql和v$sql_plan、dbms_xplan.display_cursor查出sql真实的执行计划。

select distinct s.SQL_ID, s.HASH_VALUE, s.CHILD_NUMBER, s.SQL_TEXT
  from v$sql s, v$sql_plan p
 where s.SQL_ID = p.SQL_ID
  and p.PLAN_HASH_VALUE = '3643758043';
select * from table(dbms_xplan.display_cursor(150270666, 0, 'advanced'));

性能慢的数据库:
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('10.2.0.4')
      OPT_PARAM('_complex_view_merging' 'false')
      ALL_ROWS
      ............省略............
  */

性能快的数据库: 
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('10.2.0.4')
      ALL_ROWS
      ............省略............
  */


看到两个执行的大纲有点不同,于是到两个数据库中查这个_complex_view_merging这个隐含参数,性能慢的数据库设置为false,性能快的数据库的设置则为true。

SQL语句中是有视图的,莫非这个隐含参数有问题,按字面的意思是复杂视图的合并,抱着试一试的心情调整了下这个参数:
alter session set "_complex_view_merging" = true; 

结果非常快,0.6s。

SQL> SELECT A.*,
  2        B.INCREASE_ID,
  3        B.TRANSACTION_ID,
  4        B.LINK_CARD_ID,
  5        B.VALIDATE_FLAG,
  6        B.ASSET_VALUE_SHARING,
  7        B.RELATED_DEVICE_ID,
  8        B.PARENT_CARD_CODE,
  9        B.PROJECT_VALUE,
 10        B.DELETE_FLAG,
 11        B.DEPRECIATION_ADJUST_VALUE,
 12        T.TRANSACTION_MODE_CODE,
 13        T.TRANSACTION_NO,
 14        T.TRANSACTION_FROM,
 15        T.FROM_MODEL,
 16        (SELECT T.FULL_PATH
 17            FROM sz_1230.AM_TECH_OBJECT_NODE_0900 T
 18          WHERE T.TECH_OBJECT_ID = A.DEVICE_ID
 19            AND T.NODE_TYPE = 2
 20            AND ROWNUM = 1) AS FULL_PATH,
 21        AAC.FULL_NAME CLASSIFY_FULL_PATH
 22    FROM sz_1230.V_ASSET_CARD_0900      A,
 23        sz_1230.FM_ASSET_INCREASE_ITEM B,
 24        sz_1230.FM_ASSET_TRANSACTION  T,
 25        sz_1230.AM_ASSET_CLASSIFY      AAC
 26  WHERE A.CARD_ID = B.CARD_ID
 27    AND B.TRANSACTION_ID = T.TRANSACTION_ID
 28    AND A.CLASSIFY_ID = AAC.DEVICE_CLASSIFY_ID(+)
 29    AND B.TRANSACTION_ID = '0101109514';
已选择200行。
已用时间:  00: 00: 00.06
执行计划
----------------------------------------------------------
Plan hash value: 801438153
-------------------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name                          | Rows  | Bytes | Cost (%CPU)| Time    |
-------------------------------------------------------------------------------------------------------------------
|  0 | SELECT STATEMENT                |                                |    25 | 28475 |  206  (0)| 00:00:03 |
|*  1 |  COUNT STOPKEY                  |                                |      |      |            |          |
|  2 |  TABLE ACCESS BY INDEX ROWID    | AM_TECH_OBJECT_NODE_0900      |    1 |    75 |    4  (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN              | IDX_TECH_NODE_ID_0900          |    1 |      |    3  (0)| 00:00:01 |
|  4 |  NESTED LOOPS                    |                                |    25 | 28475 |  206  (0)| 00:00:03 |
|  5 |  NESTED LOOPS OUTER            |                                |    25 | 26275 |  131  (0)| 00:00:02 |
|  6 |    NESTED LOOPS                  |                                |    25 | 24375 |  106  (0)| 00:00:02 |
|  7 |    NESTED LOOPS                |                                |    25 | 13425 |    56  (0)| 00:00:01 |
|  8 |      NESTED LOOPS                |                                |    25 |  2475 |    6  (0)| 00:00:01 |
|  9 |      TABLE ACCESS BY INDEX ROWID| FM_ASSET_TRANSACTION          |    1 |    42 |    2  (0)| 00:00:01 |
|* 10 |        INDEX UNIQUE SCAN        | PK_FM_ASSET_TRANSACTION        |    1 |      |    1  (0)| 00:00:01 |
|  11 |      TABLE ACCESS BY INDEX ROWID| FM_ASSET_INCREASE_ITEM        |    25 |  1425 |    4  (0)| 00:00:01 |
|* 12 |        INDEX RANGE SCAN          | TRANSACTION_DETAIL_REF_TRANSAC |    25 |      |    1  (0)| 00:00:01 |
|  13 |      TABLE ACCESS BY INDEX ROWID | FM_ASSET_CARD_0900            |    1 |  438 |    2  (0)| 00:00:01 |
|* 14 |      INDEX UNIQUE SCAN          | PK_FM_ASSET_CARD_0303          |    1 |      |    1  (0)| 00:00:01 |
|  15 |    TABLE ACCESS BY INDEX ROWID  | AM_ASSET_0900                  |    1 |  438 |    2  (0)| 00:00:01 |
|* 16 |      INDEX UNIQUE SCAN          | PK_AM_ASSET_0900              |    1 |      |    1  (0)| 00:00:01 |
|  17 |    TABLE ACCESS BY INDEX ROWID  | AM_ASSET_CLASSIFY              |    1 |    76 |    1  (0)| 00:00:01 |
|* 18 |    INDEX UNIQUE SCAN            | PK_AM_ASSET_CLASSIFY          |    1 |      |    0  (0)| 00:00:01 |
|  19 |  TABLE ACCESS BY INDEX ROWID    | FM_ASSET_VALUE_0900            |    1 |    88 |    3  (0)| 00:00:01 |
|* 20 |    INDEX RANGE SCAN              | ID_FAV_CARD_VALIDITY_0303      |    1 |      |    2  (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
  1 - filter(ROWNUM=1)
  3 - access("T"."TECH_OBJECT_ID"=:B1 AND "T"."NODE_TYPE"=2)
  10 - access("T"."TRANSACTION_ID"='0101109514')
  12 - access("B"."TRANSACTION_ID"='0101109514')
  14 - access("FM_ASSET_CARD"."CARD_ID"="B"."CARD_ID")
  16 - access("AM_ASSET"."DEVICE_ID"="FM_ASSET_CARD"."DEVICE_ID")
  18 - access("AM_ASSET"."CLASSIFY_ID"="AAC"."DEVICE_CLASSIFY_ID"(+))
  20 - access("FM_ASSET_VALUE"."CARD_ID"="FM_ASSET_CARD"."CARD_ID" AND
              "FM_ASSET_VALUE"."VALIDITY_DATE_END"="FM_ASSET_CARD"."DECREASE_DATE")
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
      3029  consistent gets
          0  physical reads
          0  redo size
      38039  bytes sent via SQL*Net to client
        480  bytes received via SQL*Net from client
        15  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
        200  rows processed


 于是将_complex_view_merging全局设置为true, alter system set "_complex_view_merging" = true scope=both;

 再看了下其他的oracle 10g的数据库设置都是为true,应该是安装数据库的问题。

相关推荐