分区表的global index 和 local index 跨分区查询时的性能比较

分区表的globalindex 和 local index 跨分区查询性能比较

首先初始化数据

create table tect8_tab2  partition by hash(col1) partitions 4nologging

as

select level as id ,

      dbms_random.string('p',10) as col1 ,

      dbms_random.string('p',10) as col2 ,

       dbms_random.string('p',10) as col3

 from dual

 connectby level <= 500000 ;

 

 

create table tect8_tab3 partition by hash(col1)partitions 4 nologging

as

select * from tect8_tab2 ;

 

创建索引

idx_local_tect8_tab2_col1为本地索引。(不包含partition key)

idx_local_tect8_tab3_col1为全局非分区索引。(不包含partition key)

 

create index idx_local_tect8_tab2_col2 ontect8_tab2 (col2) local ;

 

 

create index idx_local_tect8_tab3_col2 ontect8_tab3 (col2) ;

 

 

_dexter@FAKE> select index_name ,partition_name , partition_position ,object_type , blevel , leaf_blocks

  2    from user_ind_statistics

  3   where INDEX_NAME in('IDX_LOCAL_TECT8_TAB2_COL2', 'IDX_LOCAL_TECT8_TAB3_COL2')

  4   order by 1,3 ;

 

INDEX_NAME                     PARTITION_NAME                 PARTITION_POSITIONOBJECT_TYPE               BLEVEL LEAF_BLOCK

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

IDX_LOCAL_TECT8_TAB2_COL2      SYS_P141                                        1PARTITION                 1        385

IDX_LOCAL_TECT8_TAB2_COL2      SYS_P142                                        2PARTITION                 1         381

IDX_LOCAL_TECT8_TAB2_COL2      SYS_P143                                        3PARTITION                 1         385

IDX_LOCAL_TECT8_TAB2_COL2      SYS_P144                                        4PARTITION                 1         385

IDX_LOCAL_TECT8_TAB2_COL2                                                       INDEX                     1        1536

IDX_LOCAL_TECT8_TAB3_COL2                                                       INDEX                     2        1812

 

6 rows selected.

 

Local index blevel=1

Global index blevel=2

 

收集好统计信息后

 

alter session set events '10053 trace namecontext forever , level 12 ' ;

alter session set events '10046 trace namecontext forever , level 12 ' ;

select col2 from tect8_tab2 wherecol2='_=tvab9+%P' ;

select col2 from tect8_tab3 wherecol2='_=tvab9+%P' ;

alter session set events '10046 trace namecontext off ' ;

alter session set events '10053 trace namecontext off ' ;

 

开始trace

10046+10053

 

_dexter@FAKE> alter session set events '10053trace name context forever , level 12 ' ;

 

Session altered.

 

_dexter@FAKE> alter session set events '10046trace name context forever , level 12 ' ;

 

Session altered.

 

_dexter@FAKE> select col2 from tect8_tab3 where col2='_=tvab9+%P' ;

 

COL2

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

_=tvab9+%P

 

_dexter@FAKE> select col2 from tect8_tab2 where col2='_=tvab9+%P' ;

 

COL2

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

_=tvab9+%P

 

_dexter@FAKE> alter session set events '10046trace name context off ' ;

 

Session altered.

 

_dexter@FAKE> alter session set events '10053trace name context off ' ;

 

Session altered.

 

_dexter@FAKE> exit

 

首先贴出10053中的执行计划

l tab2

----- Current SQL Statement for this session(sql_id=7tx102x48qtf6) -----

 selectcol2 from tect8_tab2 where col2='_=tvab9+%P'

sql_text_length=54

sql= select col2 from tect8_tab2 wherecol2='_=tvab9+%P'

----- Explain Plan Dump -----

----- Plan Table -----

 

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

Plan Table

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

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

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

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

| 0   |SELECT STATEMENT    |                          |       |      |     5 |           |       |      |

| 1  |  PARTITION HASH ALL |                          |     1 |   11 |     5 |  00:00:01 | 1     | 4    |

| 2  |   INDEX RANGE SCAN  | IDX_LOCAL_TECT8_TAB2_COL2|     1 |   11 |     5 |  00:00:01 | 1     | 4    |

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

Predicate Information:

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

2 - access("COL2"='_=tvab9+%P')

 

l tab3

----- Current SQL Statement for this session(sql_id=d71m9kmr2u4kc) -----

 selectcol2 from tect8_tab3 where col2='_=tvab9+%P'

sql_text_length=54

sql= select col2 from tect8_tab3 wherecol2='_=tvab9+%P'

----- Explain Plan Dump -----

----- Plan Table -----

 

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

Plan Table

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

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

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

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

| 0   |SELECT STATEMENT  |                          |       |      |     3 |           |

| 1  |  INDEX RANGE SCAN |IDX_LOCAL_TECT8_TAB3_COL2|     1 |    11 |    3 |  00:00:01 |

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

Predicate Information:

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

1 - access("COL2"='_=tvab9+%P')

 

10046 trace 分析

l tab2

 

select col2

from

 tect8_tab2 where col2='_=tvab9+%P'

 

 

call    count       cpu    elapsed       disk     query    current        rows

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

Parse       1      0.06       0.03         0          0          0           0

Execute     1      0.00       0.00          0          0          0           0

Fetch       2      0.00       0.00          0          9          0           1

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

total       4      0.06       0.03          0          9          0           1

l tab3

select col2

from

 tect8_tab3 where col2='_=tvab9+%P'

 

 

call    count       cpu    elapsed       disk     query    current        rows

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

Parse       1      0.00       0.05          0          0          0           0

Execute     1      0.00       0.00          0          0          0           0

Fetch       2      0.00       0.00          0          4          0           1

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

total       4      0.00       0.05          0          4          0           1

 

 

比较一下:

 

 

Operation

Consist read

Global index

INDEX RANGE SCAN

4

Local index

PARTITION HASH ALL

-- INDEX RANGE SCAN

9

 

 

上面的语句是在OLTP系统中非常常见的短查询,可以看到。

tab3 为全局非分区索引

tab2 为本地非前缀索引(不包含partitionkey)

 

全局索引 只需要扫描较少的块。

本地索引 来说,因为是本地非前缀索引,想要扫描表中col2等于特定的值,需要扫描更多的block。

比如每个localindex 上的root block(在这里也充当branch block),这是必须的。而且就算特定的值不再此分区上,也有可能需要扫描leafblock。

为什么说可能需要扫描leafblock呢?

对于每个分区索引的存储情况可能是这样的:

partition 1 :

root block => A-Z

leaf block => ABDFG

 

partition 2 :

root block => A-Z

leaf block => ABCDFG

 

partition 3 :

root block => A-Z

leaf block => ABFG

 

partition 4 :

root block => A-Z

leaf block => ABG

 

这时候需要扫描indexvalue=c的时候,就会需要扫描

partition 1 的root block 和leaf block

partition 2 的root block 和leaf block

partition 3 的root block 和leaf block

partition 4 的root block 和leaf block

当然,真实情况可能更加复杂,这只是简单示例。

而global则不需要这么麻烦,最佳情况下只需要扫描blevel+1个block即可得到需要的列值。

 

所以OLTP系统中尽量使用global index。但是如果表分区的维护操作比较频繁(比如说经常使用分区交换技术),建议使用local index。因为如果是global index,很多操作以后(比如说分区交换),都需要重建索引,而local index则可以在预交换的表上直接创建即可。

 

10053 trace分析

 

 

_dexter@FAKE> select index_name ,partition_name , partition_position ,clustering_factor,distinct_keys

  2    from user_ind_statistics t

  3   where INDEX_NAME in('IDX_LOCAL_TECT8_TAB2_COL2', 'IDX_LOCAL_TECT8_TAB3_COL2')

  4   order by 1,3 ;

 

INDEX_NAME                    PARTITION_NAME                 PARTITION_POSITIONCLUSTERING_FACTOR DISTINCT_KEYS

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

IDX_LOCAL_TECT8_TAB2_COL2      SYS_P141                                        1            125063     125229

IDX_LOCAL_TECT8_TAB2_COL2      SYS_P142                                        2            124022     124137

IDX_LOCAL_TECT8_TAB2_COL2      SYS_P143                                        3            125094     125258

IDX_LOCAL_TECT8_TAB2_COL2      SYS_P144                                        4            125239     125376

IDX_LOCAL_TECT8_TAB2_COL2                                                                  499418     497024

IDX_LOCAL_TECT8_TAB3_COL2                                                                  499864     497024

 

6 rows selected.

 

我们来分别分析一下两个语句的10053事件。

Global index

首先复习一下优化器的工作步骤:




下面就按照顺序截取重要信息了。

 

首先是当前的sql信息

 

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

----- Current SQL Statement for this session(sql_id=d71m9kmr2u4kc) -----

 selectcol2 from tect8_tab3 where col2='_=tvab9+%P'

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

 

 

然后是优化器相关的初始化参数

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

PARAMETERS USED BY THE OPTIMIZER

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

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

 PARAMETERS WITH ALTERED VALUES

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

Compilation Environment Dump

parallel_threads_per_cpu            = 1

sqlstat_enabled                     = true

Bug Fix Control Environment

 

 

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

 PARAMETERS WITH DEFAULT VALUES

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

Compilation Environment Dump

optimizer_mode_hinted               = false

optimizer_features_hinted           = 0.0.0

parallel_execution_enabled          = true

parallel_query_forced_dop           = 0

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

 PARAMETERS IN OPT_PARAM HINT

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

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

Column Usage Monitoring is ON: tracking level =1

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

 

查询转换+谓词前推等信息

Considering Query Transformations on query blockSEL$1 (#0)

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

Query transformations (QT)

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

JF: Checking validity of join factorization forquery block SEL$1 (#0)

JF: Bypassed: not a UNIONor UNION-ALL query block.

ST: not valid since star transformationparameter is FALSE

TE: Checking validity of table expansion forquery block SEL$1 (#0)

TE: Bypassed: No relevant table found.

CBQT bypassed for query block SEL$1 (#0): nocomplex view, sub-queries or UNION (ALL) queries.

CBQT: Validity checks failed for d71m9kmr2u4kc.

CSE: Considering common sub-expressionelimination in query block SEL$1 (#0)

query block SEL$1 (#0) unchanged

FPD: Considering simple filter push in queryblock SEL$1 (#0)

"TECT8_TAB3"."COL2"='_=tvab9+%P'

try to generate transitive predicate from checkconstraints for query block SEL$1 (#0)

finally: "TECT8_TAB3"."COL2"='_=tvab9+%P'

 

apadrv-start sqlid=15241986077254029900

  :

call(in-use=980,alloc=16360), compile(in-use=52444, alloc=52728), execution(in-use=1512,alloc=4060)

没有变化

绑定变量的信息

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

Peeked values of the binds in SQL statement

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

这里没有使用绑定变量。

 

Final query

Final query after transformations:*******UNPARSED QUERY IS *******

SELECT "TECT8_TAB3"."COL2""COL2"

FROM "DEXTER"."TECT8_TAB3""TECT8_TAB3"

WHERE "TECT8_TAB3"."COL2" ='_=tvab9+%P'

 

至此,查询转换阶段结束

 

接下来就是选择最优的执行计划了

 

调整query block

kkoqbc: optimizing query block SEL$1 (#0)

       

        :

   call(in-use=1008, alloc=16360), compile(in-use=53088, alloc=56852),execution(in-use=1512, alloc=4060)

 

kkoqbc-subheap (create addr=0x1B87FB38)

 

要调整的query block

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

QUERY BLOCK TEXT

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

select col2 from tect8_tab3 wherecol2='_=tvab9+%P'

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

QUERY BLOCK SIGNATURE

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

signature (optimizer): qb_name=SEL$1 nbfros=1flg=0

  fro(0):flg=0 objn=83279 hint_alias="TECT8_TAB3"@"SEL$1"

 

相关统计信息

 

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

SYSTEM STATISTICS INFORMATION

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

  UsingNOWORKLOAD Stats

 CPUSPEEDNW: 2709 millions instructions/sec (default is 100)

 IOTFRSPEED: 4096 bytes per millisecond (default is 4096)

 IOSEEKTIM:  10 milliseconds(default is 10)

 MBRC:       NO VALUE blocks(default is 8)

 

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

BASE STATISTICAL INFORMATION

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

Table Stats::

  Table:TECT8_TAB3  Alias: TECT8_TAB3  (Using composite stats)

    #Rows: 500000  #Blks: 3049  AvgRowLen:  38.00 ChainCnt:  0.00

Index Stats::

  Index:IDX_LOCAL_TECT8_TAB3_COL1  Col#: 2

    LVLS: 2  #LB: 1812 #DK: 500000  LB/K: 1.00  DB/K: 1.00 CLUF: 499836.00

  Index:IDX_LOCAL_TECT8_TAB3_COL2  Col#: 3

LVLS: 2 #LB: 1812  #DK: 497024  LB/K: 1.00 DB/K: 1.00  CLUF: 499864.00

 

 

表的统计信息包括:

#rows 表中的行数

#blks 表中块的个数

Avgrowlen 平均长度

Chaincnt 行连接个数

 

索引统计信息包括:

lvls b tree level

#lb leaf block个数

#Dk 索引键的个数

Lb/k索引键占据的块数(LB/K—LEAF BLOCKS/KEY)

Db/k每个索引键值对应的表中数据块数(DB/K—DATABLOCKS/KEY)

Cluf 索引的聚簇因子(使用index 全扫描表中的数据,需要多少scan多少 block)

 

 

 

 

访问路径分析

Access path analysis for TECT8_TAB3

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

SINGLE TABLE ACCESS PATH

  SingleTable Cardinality Estimation for TECT8_TAB3[TECT8_TAB3]

  Column(#3): COL2(

   AvgLen: 11 NDV: 497024 Nulls: 0 Density: 0.000002

  Table:TECT8_TAB3  Alias: TECT8_TAB3

    Card: Original:500000.000000  Rounded: 1  Computed: 1.01 Non Adjusted: 1.01

  AccessPath: TableScan

    Cost:  832.36  Resp: 832.36 Degree: 0

     Cost_io: 828.00  Cost_cpu:141713271

     Resp_io: 828.00  Resp_cpu:141713271

  AccessPath: index (index (FFS))

    Index:IDX_LOCAL_TECT8_TAB3_COL2

   resc_io: 493.00  resc_cpu:97904049

   ix_sel: 0.000000 ix_sel_with_filters: 1.000000

  AccessPath: index (FFS)

    Cost:  496.01  Resp: 496.01 Degree: 1

     Cost_io: 493.00  Cost_cpu:97904049

     Resp_io: 493.00  Resp_cpu:97904049

  AccessPath: index (AllEqRange)

    Index:IDX_LOCAL_TECT8_TAB3_COL2

   resc_io: 3.00  resc_cpu: 21764

   ix_sel: 0.000002 ix_sel_with_filters: 0.000002

    Cost: 3.00  Resp: 3.00 Degree: 1

  Best:: AccessPath:IndexRange

  Index: IDX_LOCAL_TECT8_TAB3_COL2

         Cost:3.00  Degree: 1  Resp: 3.00 Card: 1.01  Bytes: 0

其中要注意的是:

Table: TECT8_TAB3  Alias: TECT8_TAB3

Card: Original: 500000.000000 Rounded: 1

Original:表示表中源数据的个数

Rounded:表示使用CBO计算后预计得到的记录个数

 

另外一个就是注意其中几个访问路径的cost

 

Cost

TableScan

832.26

index (FFS)

496.01

index (AllEqRange)

3.00

 

最后经过计算,确定最优的访问路径index (AllEqRange)。

 

Best:: AccessPath: IndexRange

  Index:IDX_LOCAL_TECT8_TAB3_COL2

         Cost:3.00  Degree: 1  Resp: 3.00 Card: 1.01  Bytes: 0

 

Explain plan

最后一个比较重要的是sqlexecute plan 。

----- Explain Plan Dump -----

----- Plan Table -----

 

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

Plan Table

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

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

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

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

| 0   |SELECT STATEMENT  |                          |       |      |     3 |           |

| 1  |  INDEX RANGE SCAN | IDX_LOCAL_TECT8_TAB3_COL2|     1 |   11 |     3 |  00:00:01 |

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

Predicate Information:

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

1 - access("COL2"='_=tvab9+%P')

 

 

Local index

Global index中的分析已经很完整,这里只给出比较重要的trace信息。

 

Final query

Final query after transformations:*******UNPARSED QUERY IS *******

SELECT "TECT8_TAB2"."COL2""COL2"

FROM "DEXTER"."TECT8_TAB2""TECT8_TAB2"

WHERE "TECT8_TAB2"."COL2" ='_=tvab9+%P'

kkoqbc: optimizing query block SEL$1 (#0)

 

 

 

相关统计信息

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

SYSTEM STATISTICS INFORMATION

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

  UsingNOWORKLOAD Stats

 CPUSPEEDNW: 2709 millions instructions/sec (default is 100)

 IOTFRSPEED: 4096 bytes per millisecond (default is 4096)

 IOSEEKTIM:  10 milliseconds(default is 10)

 MBRC:       NO VALUE blocks(default is 8)

 

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

BASE STATISTICAL INFORMATION

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

Table Stats::

  Table:TECT8_TAB2  Alias: TECT8_TAB2  (Using composite stats)

    #Rows:500000  #Blks:  3049 AvgRowLen:  38.00  ChainCnt: 0.00

Index Stats::

  Index:IDX_LOCAL_TECT8_TAB2_COL1  Col#: 2

    USINGCOMPOSITE STATS

    LVLS:1  #LB: 1536  #DK: 500000 LB/K: 1.00  DB/K: 1.00  CLUF: 499370.00

  Index:IDX_LOCAL_TECT8_TAB2_COL2  Col#: 3

    USINGCOMPOSITE STATS

    LVLS:1  #LB: 1536  #DK: 497024 LB/K: 1.00  DB/K: 1.00  CLUF: 499418.00

 

可以看到,这里使用的都是对象级别的统计信息,而不是分区级别的。

 

 

 

 

访问路径分析

 

 

 

Access path analysis for TECT8_TAB2

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

SINGLE TABLE ACCESS PATH

  SingleTable Cardinality Estimation for TECT8_TAB2[TECT8_TAB2]

  Column(#3): COL2(

   AvgLen: 11 NDV: 497024 Nulls: 0 Density: 0.000002

  Table:TECT8_TAB2  Alias: TECT8_TAB2

    Card:Original: 500000.000000  Rounded: 1  Computed: 1.01  Non Adjusted: 1.01

  AccessPath: TableScan

   Cost:  832.36  Resp: 832.36 Degree: 0

     Cost_io: 828.00  Cost_cpu:141713271

     Resp_io: 828.00  Resp_cpu:141713271

  AccessPath: index (index (FFS))

    Index:IDX_LOCAL_TECT8_TAB2_COL2

   resc_io: 417.00  resc_cpu:95938532

   ix_sel: 0.000000 ix_sel_with_filters: 1.000000

  AccessPath: index (FFS)

   Cost:  419.95  Resp: 419.95 Degree: 1

     Cost_io: 417.00  Cost_cpu:95938532

     Resp_io: 417.00  Resp_cpu:95938532

  AccessPath: index (AllEqRange)

    Index:IDX_LOCAL_TECT8_TAB2_COL2

   resc_io: 5.00  resc_cpu: 36007

   ix_sel: 0.000002 ix_sel_with_filters: 0.000002

    Cost:5.00  Resp: 5.00  Degree: 1

  Best:: AccessPath:IndexRange

  Index:IDX_LOCAL_TECT8_TAB2_COL2

         Cost:5.00  Degree: 1  Resp: 5.00 Card: 1.01  Bytes: 0

 

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

 

经过优化器的计算,得出访问TECT8_TAB2表中需要的数据,使用index range scan的方式会消耗最少的资源,所以选择它为执行计划。

 

Explain plan

----- Explain Plan Dump -----

----- Plan Table -----

 

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

Plan Table

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

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

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

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

| 0   |SELECT STATEMENT    |                          |       |      |     5 |           |       |      |

| 1  |  PARTITION HASH ALL |                          |     1 |   11 |     5 |  00:00:01 | 1     | 4    |

| 2  |   INDEX RANGE SCAN  | IDX_LOCAL_TECT8_TAB2_COL2|     1 |   11 |     5 |  00:00:01 | 1     | 4    |

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

Predicate Information:

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

2 - access("COL2"='_=tvab9+%P')

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值