解决Oracle中Split Partition缓慢的问题

解决OracleSplit Partition缓慢的问题

2011/11/17 BY MACLEAN LIU 3条评论

有这样一个case 用户的10g产品数据库中有一张按照月份划分的RANGE分区表其范围为Less than(maxvalue)的最后一个Partition分区总是为空Empty的,用户每隔半年会对这个MaxValue Partition执行Split Partition 操作,以便存放后续月份的数据,同时这个表上还有一个非分区索引Nonpartitionedindexes

 

满以为Split 这样一个Empry Partition会是一个回车就结束的任务,但是Performanceissue就在这平淡无奇的分区维护工作中出现了,实际在执行”Alter TableSplit partition Pn at (value) into …” DDL语句时,发现需要花费超过十多分钟才能完成一次Split。问题就在于,如果是有大量数据的Partition分区 Split 操作慢一些也是正常的(expected预期内的) 但是实际这里的Max Partition总是为空的,没有任何一条数据,为什么Split 一个空的分区也会是这种蜗牛的速度呢?

 

我们来模拟这个现象,首先创建一张分区表,MaxvaluePartitionEmpty的,且有一个普通索引:

 

 

SQL>select * from v$version;

 

BANNER

----------------------------------------------------------------

OracleDatabase 10g Enterprise Edition Release 10.2.0.1.0 - 64bi

PL/SQLRelease 10.2.0.1.0 - Production

CORE    10.2.0.1.0      Production

TNS forLinux: Version 10.2.0.1.0 - Production

NLSRTLVersion 10.2.0.1.0 - Production

 

SQL>select * from global_name;

 

GLOBAL_NAME

--------------------------------------------------------------------------------

www.oracledatabase12g.com& www.askmaclean.com

 

SQL>   CREATE TABLE Maclean

  2    (    "OWNER"VARCHAR2(30),

  3         "OBJECT_NAME" VARCHAR2(128),

  4         "SUBOBJECT_NAME" VARCHAR2(30),

  5         "OBJECT_ID" NUMBER,

  6         "DATA_OBJECT_ID" NUMBER,

  7         "OBJECT_TYPE" VARCHAR2(19),

  8         "CREATED" DATE,

  9         "LAST_DDL_TIME" DATE,

 10         "TIMESTAMP" VARCHAR2(19),

 11         "STATUS" VARCHAR2(7),

 12         "TEMPORARY" VARCHAR2(1),

 13         "GENERATED" VARCHAR2(1),

 14         "SECONDARY" VARCHAR2(1)

 15     )nologging

 16    partition by range(object_id)

 17    (partition p1 values less than (99999) tablespace users,

 18    partition p2 values less than (maxvalue) tablespace users);

 

Tablecreated.

 

SQL>insert /*+ append */ into maclean select * from maclean1;

 

38736384rows created.

 

SQL>commit;

 

Commitcomplete.

 

SQL>create index ind_obj onmaclean(DATA_OBJECT_ID,OBJECT_ID,LAST_DDL_TIME,TIMESTAMP,object_type,owner,status)

nologgingparallel

  2  ;

 

Indexcreated.

 

SQL>alter index ind_obj noparallel;

 

Indexaltered.

 

SQL> execdbms_stats.gather_table_stats('SYS','MACLEAN',cascade=>true,degree=>2);

 

PL/SQLprocedure successfully completed.

 

SQL>select num_rows from dba_tables where table_name='MACLEAN';

 

  NUM_ROWS

----------

  38818438

 

SQL>  select * from maclean partition (p2);

 

no rowsselected

 

/*Maclean表有大量的数据 ,但是都在p1分区中, p2分区没有任何数据 */

 

 

我们执行Split partition DDL 语句,并使用10046 level 12event监控该过程:

 

 oradebug setmypid;

 oradebug event 10046 trace name contextforever,level 12;

 

SQL>  alter table maclean split partition p2 at(100001)

  2  into (partition p3, partition p4);

 

Tablealtered.

 

[oracle@vrh8~]$ tkprof /s01/admin/G10R21/udump/g10r21_ora_4896.trc g10r21_ora_4896.tkf

 

TKPROF:Release 10.2.0.1.0 - Production on Thu Nov 17 23:42:48 2011

 

Copyright(c) 1982, 2005, Oracle.  All rightsreserved.

 

从tkf 文件中可以找出以下内容:

 

 alter table maclean split partition p2 at(100001)

 into (partition p3, partition p4)

 

call     count      cpu    elapsed       disk     query    current        rows

-------------  -------- ---------- -------------------- ----------  ----------

Parse        1     0.13       0.30         20       1139          0           0

Execute      1     0.01       0.18          3          6         33           0

Fetch        0     0.00       0.00          0         0          0           0

-------------  -------- ---------- -------------------- ----------  ----------

total        2     0.14       0.48         23       1145         33           0

 

select /*+ FIRST_ROWS PARALLEL("MACLEAN", 1) */ 1

from

 "SYS"."MACLEAN"PARTITION ("P2")  where ( (  (  ("OBJECT_ID" < 100001 )  )

  )) and rownum < 2

 

call    count       cpu   elapsed       disk     query    current        rows

-------------  -------- ---------- ---------- ---------- ---------- ----------

Parse       1      0.00      0.00         0          0         0           0

Execute     1      0.00      0.00         0         0         0           0

Fetch        1    24.85      39.15    371276    385828         0           0

-------------  -------- ---------- ---------- ---------- ---------- ----------

total       3     24.85     39.15     371276    385828         0           0

 

Misses inlibrary cache during parse: 1

Optimizermode: FIRST_ROWS

Parsinguser id: SYS   (recursive depth: 1)

 

Rows    Row Source Operation

------- ---------------------------------------------------

     0  COUNT STOPKEY (cr=385828 pr=371276 pw=0 time=39153836 us)

     0   TABLE ACCESS BY GLOBAL INDEX ROWID MACLEAN PARTITION: 2 2(cr=385828 pr=371276 pw=0 time=39153817 us)

38736384   INDEX FULL SCAN IND_OBJ (cr=385828 pr=371276 pw=0 time=309891137 us)(object id52832)

 

Elapsedtimes include waiting on following events:

 Event waitedon                            Times   Max. Wait  Total Waited

  ----------------------------------------  Waited  ----------  ------------

  db file sequentialread                   371276       0.08         19.46

 latch: cache buffers lruchain                 1       0.00          0.00

 

select /*+ FIRST_ROWS PARALLEL("MACLEAN", 1) */ 1

from

 "SYS"."MACLEAN"PARTITION ("P2")  where ( (  (  ("OBJECT_ID" >= 100001 OR

 "OBJECT_ID" IS NULL  )  )  ) ) and rownum < 2

 

call    count       cpu   elapsed       disk     query    current        rows

-------------  -------- ---------- ---------- ---------- ---------- ----------

Parse       1      0.00      0.00         0          0         0           0

Execute     1      0.00      0.00         0         0         0           0

Fetch       1      0.00      0.00         0         3         0           0

-------------  -------- ---------- ---------- ---------- ---------- ----------

total       3      0.00      0.00         0          3         0           0

 

Misses inlibrary cache during parse: 1

Optimizermode: FIRST_ROWS

Parsinguser id: SYS   (recursive depth: 1)

 

Rows    Row Source Operation

------- ---------------------------------------------------

     0  COUNT STOPKEY (cr=3 pr=0 pw=0 time=83 us)

     0   PARTITION RANGE SINGLE PARTITION: 2 2 (cr=3 pr=0 pw=0 time=63 us)

     0    TABLE ACCESS FULL MACLEAN PARTITION: 2 2 (cr=3 pr=0 pw=0time=36 us)

 

 

可以看到在执行”Alter tableSplit partition”的时候该DDL 语句产生了另外2条递归SQL(recursive sql)被调用,即上例中红色标注的SQL语句,这2条递归SQL分别以 ”OBJECT_ID” >= 100001 OR “OBJECT_ID” ISNULL   ”OBJECT_ID” < 100001 作为条件查询P2分区中的数据, Split PartitionDDL需要使用这2SQL来找出是否存在满足分隔条件过滤的数据(注意语句中有rownum<2 所以实际最多也只返回1条数据,Oracle这样来判定分隔条件的左端或右端是否有数据)

 

但是这里可以看到,其中”OBJECT_ID” <100001 作为条件的语句运行耗时39.15s产生了大量的逻辑和物理读,究其原因是该SQL的执行计划采用了Index FULL SCAN ,而另外一条以 “OBJECT_ID”>= 100001 OR “OBJECT_ID” IS NULL 作为条件的递归SQL语句则采用了TABLE ACCESS FULL MACLEAN PARTITION因为实际P2分区中是没有任何数据的,所以后者运行时间是us级别的,而前者所要扫描的是一整个没有分区的索引,这产生了大量的”db filesequential read”等待事件,我们再来看一下其执行计划:

 

 

SQL>explain plan for

  2 select /*+ FIRST_ROWSPARALLEL("MACLEAN", 1) */

  3   1

  4   from "SYS"."MACLEAN" PARTITION("P2")

  5  where (((("OBJECT_ID" < 100001))))

  6    and rownum < 2;

 

SQL>select * from table(dbms_xplan.display());

 

PLAN_TABLE_OUTPUT

-------------------------------------------------

Plan hashvalue: 985826631

 

---------------------------------------------------------------------------------------------------------------

| Id  | Operation                           | Name    | Rows | Bytes | Cost (%CPU)| Time     |Pstart| Pstop |

---------------------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT                    |         |    1 |    13 |   380K (1)| 01:16:01 |       |       |

|*  1 | COUNT STOPKEY                     |         |       |      |            |          |       |      |

|   2 |  TABLE ACCESS BY GLOBAL INDEX ROWID| MACLEAN |     1 |   13 |   380K  (1)| 01:16:01 |     2 |    2 |

|*  3 |   INDEX FULL SCAN                  | IND_OBJ |    38M|      |   380K  (1)| 01:16:01 |       |      |

---------------------------------------------------------------------------------------------------------------

 

PredicateInformation (identified by operation id):

---------------------------------------------------

 

      1 - filter(ROWNUM<2)

  3 - access("OBJECT_ID"<100001)

      filter("OBJECT_ID"<100001)

 

注意以上递归SQL中的Hint “FIRST_ROWS PARALLEL(“MACLEAN”, 1)”是该Recursive SQL所固有的,换句话说是写死在Split PartitionOracle代码层里的。

我们可以分析该Recursive SQL 采用INDEX FULL SCAN的原因可能有2种:
1. Split
所指定的分区的分区统计信息不准确,或者已经被清除。注意一旦我们Split 某个分区后该分区原有统计信息将失效,且被清除。

如下面的例子:

 

SQL>execdbms_stats.gather_table_stats('SYS','MACLEAN',cascade=>true,degree=>2);

 

PL/SQLprocedure successfully completed.

 

SQL>col high_value for a20

 

SQL>select partition_name,high_value,num_rows,blocks from dba_tab_partitions wheretable_name='MACLEAN';

 

PARTITION_NAME                 HIGH_VALUE             NUM_ROWS     BLOCKS

-------------------------------------------------- ---------- ----------

P1                             99999                  38789142     533240

P3                             100001                        0          0

P4                             MAXVALUE                      0          0

 

SQL>  alter table maclean split partition p4 at(100010)

  2  into (partition p5, partition p4);

 

这里我们再次Split 当前的MAXVALUE分区p4

 

SQL>select partition_name,high_value,num_rows,blocks from dba_tab_partitions wheretable_name='MACLEAN';

 

PARTITION_NAME                 HIGH_VALUE             NUM_ROWS     BLOCKS

-------------------------------------------------- ---------- ----------

P1                             99999                  38789142     533240

P3                             100001                        0          0

P4                             MAXVALUE

P5                             100010

 

 

可以发现Split Partiton 会导致原Partiton的统计信息失效,即便使用dbms_stats.lock_table_stats锁住统计信息也无法避免这种失效。
且单个partiton的统计信息失效并不会导致动态采用的发生(dynamicsampling)

 

SQL>show parameter dyna

 

NAME                                 TYPE        VALUE

----------------------------------------------- ------------------------------

optimizer_dynamic_sampling           integer     2

 

SQL>select * from maclean partition (p4);

 

no rowsselected

 

ExecutionPlan

----------------------------------------------------------

Plan hashvalue: 3900731449

 

--------------------------------------------------------------------------------------------------

| Id  | Operation              | Name    | Rows | Bytes | Cost (%CPU)| Time     |Pstart| Pstop |

--------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT       |        |  9699K|   860M| 29715  (2)| 00:05:57 |       |       |

|   1 | PARTITION RANGE SINGLE|        |  9699K|   860M| 29715  (2)| 00:05:57 |     4 |     4 |

|   2 |  TABLE ACCESS FULL    | MACLEAN|  9699K|   860M| 29715  (2)| 00:05:57 |     4 |     4 |

--------------------------------------------------------------------------------------------------

 

Statistics

----------------------------------------------------------

        124 recursive calls

          0 db block gets

         23 consistent gets

         0  physical reads

          0 redo size

       1139 bytes sent via SQL*Net to client

        458 bytes received via SQL*Net from client

          1 SQL*Net roundtrips to/from client

          0 sorts (memory)

          0 sorts (disk)

          0 rows processed

 

SQL>alter system flush shared_pool;

 

Systemaltered.

 

SQL>alter session set optimizer_dynamic_sampling=10;

 

Sessionaltered.

 

SQL>select * from maclean partition (p4);

 

no rowsselected

 

ExecutionPlan

----------------------------------------------------------

Plan hashvalue: 3900731449

 

--------------------------------------------------------------------------------------------------

| Id  | Operation              | Name    | Rows | Bytes | Cost (%CPU)| Time     |Pstart| Pstop |

--------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT       |        |  9699K|   860M| 29715  (2)| 00:05:57 |       |       |

| 1 | PARTITION RANGE SINGLE | | 9699K| 860M| 29715 (2)| 00:05:57 | 4 | 4|

|   2 |  TABLE ACCESS FULL    | MACLEAN|  9699K|   860M| 29715  (2)| 00:05:57 |     4 |     4 |

--------------------------------------------------------------------------------------------------

 

Statistics

----------------------------------------------------------

       5812 recursive calls

          0 db block gets

       1141 consistent gets

         22 physical reads

          0 redo size

       1139 bytes sent via SQL*Net to client

        458 bytes received via SQL*Net from client

          1 SQL*Net roundtrips to/from client

        139 sorts (memory)

          0 sorts (disk)

          0 rows processed

 

SQL>exec dbms_stats.gather_table_stats('SYS','MACLEAN',partname=>'P4');

 

PL/SQLprocedure successfully completed.

 

SQL>select * from maclean partition (p4);

 

no rowsselected

 

ExecutionPlan

----------------------------------------------------------

Plan hashvalue: 3900731449

 

--------------------------------------------------------------------------------------------------

| Id  | Operation              | Name    | Rows | Bytes | Cost (%CPU)| Time     |Pstart| Pstop |

--------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT       |        |     1 |   177 |    2   (0)| 00:00:01 |       |      |

|   1 | PARTITION RANGE SINGLE|        |     1 |   177 |    2   (0)| 00:00:01 |     4 |    4 |

|   2 |  TABLE ACCESS FULL    | MACLEAN|     1 |   177 |    2   (0)| 00:00:01 |     4 |    4 |

--------------------------------------------------------------------------------------------------

 

Statistics

----------------------------------------------------------

          0 recursive calls

          0 db block gets

          3 consistent gets

          0 physical reads

          0 redo size

       1139 bytes sent via SQL*Net to client

        458 bytes received via SQL*Net from client

          1 SQL*Net roundtrips to/from client

          0 sorts (memory)

          0 sorts (disk)

          0 rows processed

 

 

由于Split Partition 本身会导致分区的统计信息失效,这叫造成由该Split DDL所生成的递归查询SQL语句在解析时CBO Optimizer优化器无法了解该分区的必要统计信息,所以优化器会根据整张Table的统计信息来估算(根据算法来估,而没有实际的统计操作)实际统计信息中整张表有38818438 且共有4个分区,所以P4分区就顺利成长的拥有38818438 /4 = 9704k Rows实际上例中红色标注的估算值时9699k rows因为CBO 优化器得到的统计信息是该分区中有大量的数据,这导致其最终选择了 FULL INDEX SCAN的执行计划,而不是去扫描其实是空空如也的分区。

 

这是我们在 10g 中执行Split Partition 操作时需要密切注意的一个问题,解决方法是没执行一次Split PartitionDDL语句之前都收集一遍MaxValue Partiton 的统计信息,因为该分区是空的,所以这种统计是十分迅速的:

 

execdbms_stats.gather_table_stats('&OWNER','&TABNAME',partname=>'&PARNAME');

 

 

另一种手段则是在每次Split 之前都手动修改Maxvalue分区的统计信息,这样做会更快一些:

 

execdbms_stats.set_table_stats(ownname => '&OWNER',tabname =>'&TABNAME',partname => '&PARNAME',

numrows=> 0,numblks => 0,force => TRUE);

 

 

2. 另一个原因是相关的递归SQL语句被嵌入了”First Rows”hint 该提示会让CBO更倾向于使用索引以便快速返回前几行的结果,注意因为这些递归SQL实际只要求返回一行结果,所以First Rows 可以说是恰当且明智的;另外在分区表+本地分区的情景中,即便这个分区是非空的且存有大量的数据,那么使用索引都可以说是正确的选择。

 

但是在这里选择INDEX FULL SCAN 恰恰是不明智的,很显然Oracle开发部门没有为分区表+ 非分区索引(Non-partitionedIndexes) 全局索引(globalpartitioned indexes)的场景考虑该First Rows提示可能带来的后果,  已知在版本10.2.0.2 10.2.0.3 上都存在该不恰当的递归SQL hint造成的Split Partiton性能问题,Bug Note<Bug 6435544: SPLIT PARTITION SLOW BECAUSE OFHINTED RECURSIVE SQL>说明了该问题:

 

Hdr: 643554410.2.0.2.0 RDBMS 10.2.0.2.0 QRY OPTIMIZER PRODID-5 PORTID-226

Abstract:SPLIT PARTITION SLOW BECAUSE OF HINTED RECURSIVE SQL

 

PROBLEM:

--------

Splitpartition operation took more than 45 minutes to complete. Almost all

the timeis taken up by the following SQL -

select/*+ FIRST_ROWS PARALLEL("D_CUSTOMER_ORDER_ITEM_CHANNELS", 8) */ 1

from

 "BOOKER"."D_CUSTOMER_ORDER_ITEM_CHANNELS"PARTITION ("COIC101_MAX")

where ( (( ( "LEGAL_ENTITY_ID" < 101 ) )  OR  ( "LEGAL_ENTITY_ID" = 101 AND

 (

 "ORDER_DAY" < TO_DATE('2007-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS',

 'NLS_CALENDAR=GREGORIAN') )  )  ) )and rownum < 2

 

DIAGNOSTICANALYSIS:

--------------------

a. Tableis partitioned on - (LEGAL_ENTITY_ID, ORDER_DAY).

   Index PK_D_CUST_ORDER_ITEM_CHANNELS is on -

       (CUSTOMER_ORDER_ITEM_ID, MARKETPLACE_ID,LEGAL_ENTITY_ID, ORDER_DAY)

 

b. Tablehas 555 partitions. Index is a global index.

 

c. Fromthe tkprof output -

 

call   count      cpu    elapsed       disk     query  current  rows

-----------  -------- ---------- -------------------- --------  ----

Parse      1     0.00       0.00          0          0        0    0

Execute    1     0.00       0.00          0          0        0    0

Fetch      1   405.50    2796.28    1408207   1444973        0    0

-----------  -------- ---------- -------------------- --------  ----

total      3   405.50    2796.28    1408207   1444973        0     0

 

Misses inlibrary cache during parse: 1

Optimizermode: FIRST_ROWS

Parsinguser id: 108     (recursive depth: 1)

 

Rows     Row Source Operation

------- ---------------------------------------------------

time=6us)(object id 1160811)

 

d.Although we have partition_name in the query, we go for INDEX FULL scan

becauseof hard coded hint FIRST_ROWS. A FTS of the concerned partition would

be muchfaster in this case.

 

WORKAROUND:

-----------

Drop theglobal index which would force an FTS on a single partition.

 

RELEASENOTES:

]] Poorperformance was possible for ALTER TABLE SPLIT PARTITION if there

]] was anindex on the partition key.

REDISCOVERYINFORMATION:

If youget poor performance for an ALTER TABLE SPLIT PARTITION operation

and thereis an index on the partition key, you may be hitting this bug.

WORKAROUND:

None

 

 

Metalink给出的Workaround方案是将分区表上的global index 全局索引drop 掉,这样可以让CBO只能选择对single partitionFULL TABLE SCAN

 

实际上这个Solution并很不能让人满意,在产品环境中我们不可能随意drop掉某张关键表上的索引,所以这个solution的可操作性很低。

 

补充:我们来看一下First Rows Hint CBO计算成本时如何起作用的:

 

SQL>oradebug setmypid;

Statementprocessed.

SQL>oradebug event 10053 trace name context forever,level 1;

Statementprocessed.

SQL>explain plan for select /*+ FIRST_ROWS PARALLEL("MACLEAN", 1) */

  2   1

  3   from "SYS"."MACLEAN" PARTITION("P4")

  4  where (((("OBJECT_ID" < 100010))))

  5    and rownum < 2; Explained. SQL> oradebug tracefile_name;

 

10053trace content ================================================

 

  *************************************

  PARAMETERS WITH ALTERED VALUES

  ******************************

  optimizer_mode_hinted               = true

  optimizer_mode                      = first_rows

 

***************************************

BASESTATISTICAL INFORMATION

***********************

TableStats::

 Table: MACLEAN  Alias: MACLEAN  Partition [3]

   #Rows: 0  #Blks:  1  AvgRowLen:  0.00

   #Rows: 0  #Blks:  1  AvgRowLen:  0.00

IndexStats::

 Index: IND_OBJ  Col#: 5 4 8 9 6 1 10

   LVLS: 3  #LB: 380544  #DK: 50447  LB/K: 7.00  DB/K:777.00  CLUF: 39208542.00

***************************************

SINGLETABLE ACCESS PATH

 Column (#4): OBJECT_ID(NUMBER)  Part#: 3

   AvgLen: 22.00 NDV: 0 Nulls: 0 Density: 0.0000e+00 Min: 0 Max: 0

 Column (#4): OBJECT_ID(NUMBER)

   AvgLen: 22.00 NDV: 0 Nulls: 0 Density: 0.0000e+00 Min: 0 Max: 0

 Table: MACLEAN  Alias: MACLEAN     

   Card: Original: 0  Rounded: 1  Computed: 0.00  Non Adjusted:0.00

 Access Path: TableScan

   Cost:  2.00  Resp: 2.00  Degree: 0

     Cost_io: 2.00  Cost_cpu: 7121

     Resp_io: 2.00  Resp_cpu: 7121

kkofmx:index filter:"MACLEAN"."OBJECT_ID"<100010 ANDROWNUM<2

  AccessPath: index (skip-scan)

   SS sel: 0.0000e+00  ANDV (#skips): 4073

   SS io: 32584.00 vs. table scan io: 2.00

   Skip Scan rejected

 Access Path: index (FullScan)

   Index: IND_OBJ

   resc_io: 380547.00  resc_cpu: 10551751028

   ix_sel: 1  ix_sel_with_filters: 1

   Cost: 382007.38  Resp: 382007.38  Degree: 1

 Best:: AccessPath: IndexRange  Index: IND_OBJ

        Cost: 382007.38  Degree: 1  Resp: 382007.38  Card: 0.00 Bytes: 0

***************************************

OPTIMIZERSTATISTICS AND COMPUTATIONS

***************************************

GENERALPLANS

***************************************

Consideringcardinality-based initial join order.

***********************

Joinorder[1]:  MACLEAN[MACLEAN]#0

***********************

Best sofar: Table#: 0  cost: 382007.3822  card: 0.0000  bytes: 13

(newjo-stop-1)k:0, spcnt:0, perm:1, maxperm:80000

*********************************

Number ofjoin permutations tried: 1

*********************************

prefetchingis on for IND_OBJ

Final - First Rows Plan:  Best join order: 1

 Cost: 382007.3822  Degree: 1  Card: 1.0000  Bytes: 13

 Resc: 382007.3822  Resc_io: 380547.0000  Resc_cpu: 12512178128

 Resp: 382007.3822  Resp_io: 380547.0000  Resc_cpu: 12512178128

kkoipt:Query block SEL$1 (#0)

*******UNPARSED QUERY IS *******

SELECT/*+ FIRST_ROWS NO_PARALLEL ("MACLEAN") */ 1 "1" FROM"SYS"."MACLEAN" PARTITION ("P4") 

"MACLEAN"WHERE ROWNUM<2 AND "MACLEAN"."OBJECT_ID"<100010

kkoqbc-end

         : call(in-use=46464, alloc=49080), compile(in-use=39288, alloc=40552)

apadrv-end:call(in-use=46464, alloc=49080), compile(in-use=40072, alloc=40552)

 

sql_id=ff1ft3uxsq105.

CurrentSQL statement for this session:

explainplan for select /*+ FIRST_ROWS PARALLEL("MACLEAN", 1) */

 1

 from "SYS"."MACLEAN" PARTITION("P4")

 where(((("OBJECT_ID" < 100010))))

  and rownum < 2

 

============

PlanTable

============

-------------------------------------------------------+-----------------------------------+---------------+

|Id  |Operation                           | Name    | Rows  | Bytes | Cost  |Time      | Pstart| Pstop |

-------------------------------------------------------+-----------------------------------+---------------+

|0   | SELECTSTATEMENT                    |        |       |      |  373K |          |       |       |

|1   |  COUNTSTOPKEY                      |        |       |      |      |          |       |       |

|2   |   TABLE ACCESS BY GLOBAL INDEX ROWID | MACLEAN|     1 |    13 |  373K | 01:16:25 | 4     | 4     |

|3   |    INDEX FULLSCAN                  | IND_OBJ |   37M |       |  373K|  01:16:25 |       |      |

-------------------------------------------------------+-----------------------------------+---------------+

PredicateInformation:

----------------------

1 - filter(ROWNUM<2)

3 -access("OBJECT_ID"<100010)

3 -filter("OBJECT_ID"<100010)

 

Contentof other_xml column

===========================

 db_version     : 10.2.0.1

 parse_schema   : SYS

 plan_hash      : 985826631

 Outline Data:

 /*+

   BEGIN_OUTLINE_DATA

     IGNORE_OPTIM_EMBEDDED_HINTS

     OPTIMIZER_FEATURES_ENABLE('10.2.0.1')

     FIRST_ROWS

     OUTLINE_LEAF(@"SEL$1")

     INDEX(@"SEL$1" "MACLEAN"@"SEL$1"("MACLEAN"."DATA_OBJECT_ID""MACLEAN"."OBJECT_ID"

"MACLEAN"."LAST_DDL_TIME""MACLEAN"."TIMESTAMP""MACLEAN"."OBJECT_TYPE" "MACLE

AN"."OWNER""MACLEAN"."STATUS"))

   END_OUTLINE_DATA

  */

 

 

可以看到虽然INDEX FULL SCAN的成本(cost:382007)大于 Access Path:TableScan (cost : 2.00) 很多,但是optimizer 最终仍然选择了Index Full Scan 因为其是满足First Rows 要求的执行计划(红色标注部分)

 

于是我开始自己寻找workaround的路径,目标是让优化器忽略”First Rows”的影响。我一开始寄望于能够通过设置一些影响CBO计算cost的优化器参数来让optimizer 迷途知返,包括设置optimizer_index_cost_adj”_db_file_optimizer_read_count”的值到一个很大水平,但发现并不起作用:

 

SQL>alter session set "_db_file_optimizer_read_count"=65535;

 

Sessionaltered.

 

SQL>  alter session setoptimizer_index_cost_adj=10000;

 

Sessionaltered.

 

SQL>alter system flush shared_pool;

 

Systemaltered.

 

SQL>select /*+ FIRST_ROWS PARALLEL("MACLEAN", 1) */

  2   1

  3   from "SYS"."MACLEAN" PARTITION("P4")

  4  where (((("OBJECT_ID" < 100010))))

  5    and rownum < 2;

 

no rowsselected

 

ExecutionPlan

----------------------------------------------------------

Plan hashvalue: 985826631

 

---------------------------------------------------------------------------------------------------------------

| Id  | Operation                           | Name    | Rows | Bytes | Cost (%CPU)| Time     |Pstart| Pstop |

---------------------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT                    |         |    1 |    13 |    38M (1)|127:20:09 |       |       |

|*  1 | COUNT STOPKEY                     |         |       |      |            |          |       |      |

|   2 |  TABLE ACCESS BY GLOBAL INDEX ROWID| MACLEAN |     1 |   13 |    38M  (1)|127:20:09 |     4 |    4 |

|*  3 |   INDEX FULL SCAN                  |IND_OBJ |    39M|       |   38M  (1)|127:20:09 |       |      |

---------------------------------------------------------------------------------------------------------------

 

得益于好奇心,我以’%optimizer%ignore’Like语句去查了Oracle的隐式参数表,果然有志者事竟成,最终有所斩获:

 

SQL>col name for a40

SQL>col value for a20

SQL>col describ for a60

SQL>set linesize 200 pagesize 1400

SQL>SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ

  2  FROM SYS.x$ksppi x, SYS.x$ksppcv y

  3  WHERE x.inst_id = USERENV ('Instance')

  4   ANDy.inst_id = USERENV ('Instance')

  5   ANDx.indx = y.indx

  6  ANDx.ksppinm LIKE '%optimizer%ignore%';

 

NAME                                     VALUE                DESCRIB

------------------------------------------------------------ ---------------------

_optimizer_ignore_hints                  TRUE                 enables the embedded hints tobe ignored

 

 

metalink上查了下没有关于该”_optimizer_ignore_hints” 隐式参数的任何有用信息,就注释来看是可以启用是否忽略SQL中嵌入的HINT提示信息,我们来具体看以下是否其作用:

 

 

SQL>alter system flush shared_pool;

 

Systemaltered.

 

SQL>explain plan for select /*+ FIRST_ROWS PARALLEL("MACLEAN", 1) */

  2   1

  3   from "SYS"."MACLEAN" PARTITION("P4")

  4  where (((("OBJECT_ID" < 100010))))

  5    and rownum < 2;

 

Explained.

 

SQL>select * from table(dbms_xplan.display());

 

PLAN_TABLE_OUTPUT

---------------------------------------------

Plan hashvalue: 985826631

 

---------------------------------------------------------------------------------------------------------------

|Id  |Operation                          | Name    | Rows  | Bytes | Cost (%CPU)| Time    | Pstart| Pstop |

---------------------------------------------------------------------------------------------------------------

|  0 | SELECTSTATEMENT                   |         |     1|    13 |    38M  (1)|127:20:09|       |       |

|* 1 |  COUNTSTOPKEY                     |         |      |      |           |         |       |       |

|  2 |   TABLE ACCESS BY GLOBAL INDEX ROWID| MACLEAN|     1 |    13 |   38M  (1)|127:20:09 |     4 |     4|

|* 3 |    INDEX FULLSCAN                 | IND_OBJ |    39M|      |    38M  (1)|127:20:09|       |       |

---------------------------------------------------------------------------------------------------------------

 

PredicateInformation (identified by operation id):

---------------------------------------------------

 

  1 - filter(ROWNUM<2)

  3 - access("OBJECT_ID"<100010)

      filter("OBJECT_ID"<100010)

 

SQL> alter session set "_optimizer_ignore_hints"=true;

 

Sessionaltered.

 

SQL>oradebug setmypid;

Statementprocessed.

 

SQL>oradebug event 10053 trace name context forever , level 1;

Statementprocessed.

 

SQL>explain plan for select /*+ FIRST_ROWS PARALLEL("MACLEAN", 1) */

  2   1

  3   from "SYS"."MACLEAN" PARTITION("P4")

  4  where (((("OBJECT_ID" < 100010))))

  5    and rownum < 2; Explained. SQL> select * from table(dbms_xplan.display());

 

PLAN_TABLE_OUTPUT

-----------------------------------------------

Plan hashvalue: 4280157877

 

---------------------------------------------------------------------------------------------------

|Id  |Operation              | Name    | Rows  | Bytes | Cost (%CPU)|Time     | Pstart| Pstop |

---------------------------------------------------------------------------------------------------

|  0 | SELECT STATEMENT       |         |     1|    13 |     2   (0)| 00:00:01|       |       |

|* 1 |  COUNT STOPKEY         |        |       |      |           |         |       |       |

|  2 |   PARTITION RANGESINGLE|        |     1 |    13 |    2   (0)| 00:00:01 |     4 |    4 |

|* 3 |    TABLE ACCESS FULL    | MACLEAN|     1 |    13 |    2   (0)| 00:00:01 |     4|     4 |

---------------------------------------------------------------------------------------------------

 

PredicateInformation (identified by operation id):

---------------------------------------------------

 

  1 - filter(ROWNUM<2)

  3 - filter("OBJECT_ID"<100010)

 

惊喜! 该“_optimizer_ignore_hints”参数确实起到无视HINT提示的作用,且可以直接在session级别修改,十分方便,我们透过10053 event来观察该参数是如何其作用的:

 

***************************************

PARAMETERSUSED BY THE OPTIMIZER

********************************

  *************************************

  PARAMETERS WITH ALTERED VALUES

  ******************************

  _optimizer_ignore_hints             = true

 

***************************************

BASESTATISTICAL INFORMATION

***********************

TableStats::

 Table: MACLEAN  Alias: MACLEAN  Partition [3]

   #Rows: 0  #Blks:  1  AvgRowLen:  0.00

   #Rows: 0  #Blks:  1  AvgRowLen:  0.00

IndexStats::

 Index: IND_OBJ  Col#: 5 4 8 9 6 1 10

   LVLS: 3  #LB: 380544  #DK: 50447  LB/K: 7.00  DB/K:777.00  CLUF: 39208542.00

***************************************

SINGLETABLE ACCESS PATH

 Column (#4): OBJECT_ID(NUMBER)  Part#: 3

   AvgLen: 22.00 NDV: 0 Nulls: 0 Density: 0.0000e+00 Min: 0 Max: 0

 Column (#4): OBJECT_ID(NUMBER)

   AvgLen: 22.00 NDV: 0 Nulls: 0 Density: 0.0000e+00 Min: 0 Max: 0

 Table: MACLEAN  Alias: MACLEAN

   Card: Original: 0  Rounded: 1  Computed: 0.00  Non Adjusted:0.00

 Access Path: TableScan

   Cost:  2.00  Resp: 2.00  Degree: 0

     Cost_io: 2.00  Cost_cpu: 7121

     Resp_io: 2.00  Resp_cpu: 7121

kkofmx:index filter:"MACLEAN"."OBJECT_ID"<100010 ANDROWNUM<2

 Access Path: index (skip-scan)

   SS sel: 0.0000e+00  ANDV (#skips): 4073

   SS io: 32584.00 vs. table scan io: 2.00

   Skip Scan rejected

 Access Path: index (FullScan)

   Index: IND_OBJ

   resc_io: 380547.00  resc_cpu: 10551751028

   ix_sel: 1  ix_sel_with_filters: 1

   Cost: 382007.38  Resp: 382007.38  Degree: 1

 Best:: AccessPath: TableScan

***************************************

OPTIMIZERSTATISTICS AND COMPUTATIONS

***************************************

GENERALPLANS

***************************************

Consideringcardinality-based initial join order.

***********************

Joinorder[1]:  MACLEAN[MACLEAN]#0

***********************

Best sofar: Table#: 0  cost: 2.0008  card: 0.0000  bytes: 13

(newjo-stop-1)k:0, spcnt:0, perm:1, maxperm:80000

*********************************

Number ofjoin permutations tried: 1

*********************************

Final -All Rows Plan:  Best join order: 1

 Cost: 2.0008  Degree: 1  Card: 1.0000  Bytes: 13

 Resc: 2.0008  Resc_io: 2.0000  Resc_cpu: 7121

 Resp: 2.0008  Resp_io: 2.0000  Resc_cpu: 7121

 

CurrentSQL statement for this session:

explainplan for select /*+ FIRST_ROWS PARALLEL("MACLEAN", 1) */

 1

 from "SYS"."MACLEAN" PARTITION("P4")

 where(((("OBJECT_ID" < 100010))))

  and rownum < 2

 

============

PlanTable

============

-------------------------------------------+-----------------------------------+---------------+

|Id  |Operation               | Name    | Rows  | Bytes | Cost  |Time      | Pstart| Pstop |

-------------------------------------------+-----------------------------------+---------------+

|0   | SELECTSTATEMENT        |        |       |      |     2|          |       |       |

|1   |  COUNTSTOPKEY          |        |       |      |      |          |       |       |

|2   |   PARTITION RANGE SINGLE|         |     1|    13 |     2 |  00:00:01 |4     | 4     |

|3   |    TABLE ACCESS FULL     |MACLEAN |     1 |    13|     2 |  00:00:01 | 4     |4     |

-------------------------------------------+-----------------------------------+---------------+

PredicateInformation:

----------------------

1 -filter(ROWNUM<2)

3 -filter("OBJECT_ID"<100010)

 

Contentof other_xml column

===========================

 db_version     : 10.2.0.1

 parse_schema   : SYS

 plan_hash      : 4280157877

 Outline Data:

 /*+

   BEGIN_OUTLINE_DATA

      IGNORE_OPTIM_EMBEDDED_HINTS

     OPTIMIZER_FEATURES_ENABLE('10.2.0.1')

      ALL_ROWS

     OUTLINE_LEAF(@"SEL$1")

      FULL(@"SEL$1""MACLEAN"@"SEL$1")

   END_OUTLINE_DATA

  */

 

DumpingHints

=============

 atom_hint=(@=0x988453c0 err=20 resol=1 used=0 token=453 org=1 lvl=2 txt=FIRST_ROWS)

 atom_hint=(@=0x988451f8 err=0 resol=1 used=1 token=177 org=1 lvl=3txt=NO_PARALLEL ("MACLEAN") )

**********WARNING: SOME HINTS HAVE ERRORS *********

 

实际“_optimizer_ignore_hints”参数是起到的作用是使SQL 隐式地回归到默认的optimizer_mode=ALL_ROWS上来,  我们终于战胜了嵌入在SQL语句中的”First Rows”Hint

 

总结

在针对10g 多个版本上的Split Partition 可能因DDL所附带的递归SQL 使用了固定的而又不恰当的”First rowsHint” 提示而造成语句执行缓慢的问题,我们可以通过以下3个方案解决:

A.  通过每次执行Split之前都收集指定分区的统计,并设置”_optimizer_ignore_hints” =true 来规避分区统计信息失效和不恰当的”First Rowshint” 所可能带来的问题,方法如下:

execdbms_stats.gather_table_stats('&OWNER','&TABNAME',partname=>'&PARNAME');

 

altersession set "_optimizer_ignore_hints"=true;

推荐使用方案A

补充:

有同学反映:

隐藏参数_optimizer_ignore_hints在分区表的split操作中并未启到作用。

从我的测试结果来看,虽然导致split操作慢的根源是FIRST_ROWS优化器模式下的分区表select语句:

select /*+ FIRST_ROWSPARALLEL(“MACLEAN”, 1) */ 1 
from
 MACLEAN PARTITION (“P4″)  where ((  (  ( 
  “OBJECT_ID” < ’1000010′ ) )  ) ) and rownum < 2;

不过以上的sql语句在_optimizer_ignore_hints参数调整后仍使用FIRST_ROWS的优化器模式,即没有生效。

我觉得这可能与oracle在执行自己内部命令时,会忽略该参数的设置。(直接执行selectsql语句确实会忽略hint

 

实际通过10053 事件追踪该SPLIT PARTITION DDL语句所生产的递归SQL语句,发现带有”FIRST_ROWS”提示的SELECT语句甚至没有解析的过程,很有可能是该递归SQL语句直接使用了内部硬编码的存储大纲OUTLINES所导致的。

 

换句话说之前_optimizer_ignore_hints的隐式参数针对我们手动执行的带有FIRST_ROWS HINTSELECT语句是有效的,而对于DDL所附带的递归SQL无效。

 

注:实际在对嵌入了HINT的非recursive SQL语句做调优时,若我们无法修改该SQLHINT,则还是可以利用到”_optimizer_ignore_hints”的。

 

想了一下可以通过设置较旧的优化器特性了解决该问题(alter sessionset optimizer_features_enable=’8.0.0′;),该optimizer_features_enable参数同样可以在session级别设置,如:

 

TEST A:

 

SQL>set timing on;

 

SQL> oradebugsetmypid;

Statementprocessed.

 

SQL>oradebug event 10046 trace name context forever,level 12;

Statementprocessed.

 

SQL>oradebug tracefile_name;

/s01/admin/G10R21/udump/g10r21_ora_13646.trc

 

SQL>alter table maclean split partition p4 at (10000081) into (partition p14,partition p4);

 

Tablealtered.

 

Elapsed:00:00:42.50

 

TEST B:

 

SQL>set timing on;

 

SQL>oradebug setmypid;

Statementprocessed.

 

SQL>oradebug tracefile_name;

/s01/admin/G10R21/udump/g10r21_ora_13656.trc

 

SQL> alter session set optimizer_features_enable='8.0.0';

 

Sessionaltered.

 

Elapsed:00:00:00.01

 

SQL>alter table maclean split partition p4 at (10000091) into (partition p15,partition p4);

 

Tablealtered.

 

Elapsed: 00:00:00.05

 

PARSINGIN CURSOR #2 len=152 dep=1 uid=0 oct=3 lid=0 tim=1291531645417871 hv=2124209225ad='a74b41f0'

 

select/*+ FIRST_ROWS PARALLEL("MACLEAN", 1) */ 1 from"SYS"."MACLEAN" PARTITION ("P4") 

where ((  (  ( "OBJECT_ID" < 10000091 )  )  ) ) andrownum < 2

END OFSTMT

PARSE#2:c=1000,e=684,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=2,tim=1291531645417864

BINDS #2:

EXEC#2:c=0,e=71,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=2,tim=1291531645417984

FETCH#2:c=0,e=92,p=0,cr=3,cu=0,mis=0,r=0,dep=1,og=2,tim=1291531645418094

STAT #2id=1 cnt=0 pid=0 pos=1 obj=0 op='COUNT STOPKEY (cr=3 pr=0 pw=0 time=122 us)'

STAT #2id=2 cnt=0 pid=1 pos=1 obj=0 op='PARTITION RANGE SINGLE PARTITION: 13 13 (cr=3pr=0 pw=0 time=95 us)'

STAT #2id=3 cnt=0 pid=2 pos=1 obj=52809 op='TABLE ACCESS FULL MACLEAN PARTITION: 13 13(cr=3 pr=0 pw=0 time=59 us)'

=====================

 

PARSINGIN CURSOR #2 len=177 dep=1 uid=0 oct=3 lid=0 tim=1291531645418799 hv=339345368ad='a74cedd8'

select/*+ FIRST_ROWS PARALLEL("MACLEAN", 1) */ 1 from"SYS"."MACLEAN" PARTITION ("P4")

 where( (  (  ( "OBJECT_ID" >= 10000091 OR"OBJECT_ID" IS NULL  )  )  ) ) and

rownum< 2

END OFSTMT

PARSE#2:c=1000,e=589,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=2,tim=1291531645418792

BINDS #2:

EXEC#2:c=0,e=67,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=2,tim=1291531645418908

FETCH#2:c=0,e=66,p=0,cr=3,cu=0,mis=0,r=0,dep=1,og=2,tim=1291531645418992

STAT #2id=1 cnt=0 pid=0 pos=1 obj=0 op='COUNT STOPKEY (cr=3 pr=0 pw=0 time=92 us)'

STAT #2id=2 cnt=0 pid=1 pos=1 obj=0 op='PARTITION RANGE SINGLE PARTITION: 13 13 (cr=3pr=0 pw=0 time=64 us)'

STAT #2id=3 cnt=0 pid=2 pos=1 obj=52809 op='TABLE ACCESS FULL MACLEAN PARTITION: 13 13(cr=3 pr=0 pw=0 time=36 us)'

WAIT #1:nam='control file sequential read' ela= 31 file#=0 block#=1 blocks=1 obj#=-1tim=1291531645419383

WAIT #1:nam='control file sequential read' ela= 12 file#=1 block#=1 blocks=1 obj#=-1tim=1291531645419432

WAIT #1:nam='control file sequential read' ela= 23 file#=0 block#=15 blocks=1 obj#=-1tim=1291531645419494

WAIT #1:nam='control file sequential read' ela= 10 file#=0 block#=17 blocks=1 obj#=-1 tim=1291531645419556

 

B. 如果确实遇到了该问题,也可以将Index FULL SCAN 所使用的全局索引drop 掉来达到强制使用FULL singletable partition SCAN的目的,实际使用中不推荐

C. 避免使用GlobalPartitioned index Non-partitioned Index 而采用Localpartitioned index 这似乎更难做到

D. 也可以通过将原Maxvalue的分区drop掉之后(前提是该分区真的是空的),再添加新分区的做法来绕过该问题

相关文章 | Relatedposts:

1.   11g新特性:Note raised when explain plan for create index

2.   Extract SQL Plan from AWR

3.   部分行索引使用介绍

4.   Script:List OBJECT DEPENDENT

5.   11g新动态性能视图V$SQL_MONITOR,V$SQL_PLAN_MONITOR

6.   Gather more plan statistics bygather_plan_statistics hint

7.   OPT_PARAM Hint

FILEDUNDER: ORACLEORACLE分区技术PARTITION TAGGEDWITH: CBOHINTPARTITION_OPTIMIZER_IGNORE_HINTS

最新最早最热

·        3条评论

·        

xs

good,有机会用用

20111118回复转发

o   

maclean

补充:
有同学反映:
隐藏参数_optimizer_ignore_hints在分区表的split操作中并未启到作用。

从我的测试结果来看,虽然导致split操作慢的根源是FIRST_ROWS优化器模式下的分区表select语句:

select /*+ FIRST_ROWS PARALLEL("MACLEAN", 1) */ 1 
from
MACLEAN PARTITION ("P4") where ( ( ( ( 
"OBJECT_ID" < '1000010' ) ) ) ) and rownum set timing on;

SQL> oradebug setmypid;
Statement processed.

SQL> oradebug event 10046 trace name context forever,level 12;
Statement processed.

SQL> oradebug tracefile_name;
/s01/admin/G10R21/udump/g10r21_ora_13646.trc

SQL> alter table maclean split partition p4 at (10000081) into (partitionp14, partition p4);

Table altered.

Elapsed: 00:00:42.50





TEST B:

SQL> set timing on;
SQL> oradebug setmypid;
Statement processed.
SQL> oradebug tracefile_name;
/s01/admin/G10R21/udump/g10r21_ora_13656.trc

SQL> alter session set optimizer_features_enable='8.0.0';

Session altered.

Elapsed: 00:00:00.01
SQL> alter table maclean split partition p4 at (10000091) into (partitionp15, partition p4);

Table altered.

Elapsed: 00:00:00.05


PARSING IN CURSOR #2 len=152 dep=1 uid=0 oct=3 lid=0 tim=1291531645417871hv=2124209225 ad='a74b41f0'
select /*+ FIRST_ROWS PARALLEL("MACLEAN", 1) */ 1 from"SYS"."MACLEAN" PARTITION ("P4") where ( ( ( ("OBJECT_ID" < 10000091 ) ) ) ) and rownum = 10000091 OR"OBJECT_ID" IS NULL ) ) ) ) and
rownum < 2
END OF STMT
PARSE #2:c=1000,e=589,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=2,tim=1291531645418792
BINDS #2:
EXEC #2:c=0,e=67,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=2,tim=1291531645418908
FETCH #2:c=0,e=66,p=0,cr=3,cu=0,mis=0,r=0,dep=1,og=2,tim=1291531645418992
STAT #2 id=1 cnt=0 pid=0 pos=1 obj=0 op='COUNT STOPKEY (cr=3 pr=0 pw=0 time=92us)'
STAT #2 id=2 cnt=0 pid=1 pos=1 obj=0 op='PARTITION RANGE SINGLE PARTITION: 1313 (cr=3 pr=0 pw=0 time=64 us)'
STAT #2 id=3 cnt=0 pid=2 pos=1 obj=52809 op='TABLE ACCESS FULL MACLEANPARTITION: 13 13 (cr=3 pr=0 pw=0 time=36 us)'
WAIT #1: nam='control file sequential read' ela= 31 file#=0 block#=1 blocks=1obj#=-1 tim=1291531645419383
WAIT #1: nam='control file sequential read' ela= 12 file#=1 block#=1 blocks=1obj#=-1 tim=1291531645419432
WAIT #1: nam='control file sequential read' ela= 23 file#=0 block#=15 blocks=1obj#=-1 tim=1291531645419494
WAIT #1: nam='control file sequential read' ela= 10 file#=0 block#=17 blocks=1obj#=-1 tim=1291531645419556

 

你可能感兴趣的:(解决Oracle中Split Partition缓慢的问题)