oracle 12c R1执行计划新特性-table access by index rowid batched和INMOMEORY OPTION

oracle 12c R1执行计划在索引回表阶段oracle推出了batched特性,类似于oracle 11g中在nested loop中被驱动表回表时的向量IO,也是为了有效的解决表中数据无序性(索引的聚簇因子),下面看实际测试用例:

数据库版本:12.1.0.2版本

sys@CRMDB2>
explain plan for SELECT offering_inst_id,
       offering_id,
       owner_party_role_type,
       owner_party_role_id,
       purchase_seq,
       brand,
       primary_flag,
       rel_pri_offering_inst_id,
       bundle_flag,
       p_offering_inst_id,
       apply_obj_type,
       apply_obj_id,
       status,
       status_detail,
       status_date,
       eff_date,
       。。。。。。
  FROM transdata.bk_INF_OFFERING_INST t
 WHERE be_id = 18
   AND modify_time <= to_date(20151104 || 235959, 'yyyymmddhh24miss')
   AND modify_time >= to_date(20151104 || 0, 'yyyymmddhh24miss')
   AND SUBS_ID >= 1842201100000000
   AND SUBS_ID < 1842211100000000;

sys@CRMDB2>select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3059718575

--------------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name                  | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |                       |     1 |   165 |  5118   (1)| 00:00:01 |
|*  1 |  FILTER                              |                       |       |       |            |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID BATCHED| BK_INF_OFFERING_INST  |     1 |   165 |  5118   (1)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN                  | IDX_INF_OFFERING_CQL1 | 28466 |       |    87   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(TO_DATE('201511040','yyyymmddhh24miss')<=TO_DATE(' 2015-11-04 23:59:59', 'syyyy-mm-dd
              hh24:mi:ss'))
   2 - filter("MODIFY_TIME">=TO_DATE('201511040','yyyymmddhh24miss') AND "MODIFY_TIME"<=TO_DATE('
              2015-11-04 23:59:59', 'syyyy-mm-dd hh24:mi:ss') AND "BE_ID"=18)
   3 - access("SUBS_ID">=1842201100000000 AND "SUBS_ID"<1842211100000000)

19 rows selected.

执行计划中的table access by index rowid batched,这个是12.1中的新特性,主要是在通过rowid访问数据块时,对于一个数据块中的多个rowid,通过批量访问减少访问块的次数,该特性由隐含参数_optimizer_batch_table_access_by_rowid来控制,该参数默认为true,也就是开启这个特性。

sys@CRMDB2>select a.ksppinm, a.ksppdesc,b.ksppstvl,a.inst_id
  2    from x$ksppi a, x$ksppcv b
  3   where a.inst_id = 1
  4     and a.ksppinm = '&param'
  5     and a.indx = b.indx;
Enter value for param: _optimizer_batch_table_access_by_rowid
old   4:    and a.ksppinm = '&param'
new   4:    and a.ksppinm = '_optimizer_batch_table_access_by_rowid'

KSPPINM                        KSPPDESC                       KSPPSTVL                          INST_ID
------------------------------ ------------------------------ ------------------------------ ----------
_optimizer_batch_table_access_ enable table access by ROWID I TRUE                                    1
by_rowid                       O batching

12.1.0.2版本中,oracle正式发布了内存和列式计算的In-Memory Option,In-Meomory option列存与压缩,数据在内存的独立区域中按照列式存储,数据是被压缩存放的,内存与列式存储可以极大提升查询的性能

SQL> show sga;
Total System Global Area  599785472 bytes
Fixed Size                  2927192 bytes
Variable Size             335545768 bytes
Database Buffers          150994944 bytes
Redo Buffers                5459968 bytes
In-Memory Area            104857600 bytes

IMO的特性相关的参数:
SQL> show parameter inmemory;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
inmemory_clause_default              string
inmemory_force                       string      DEFAULT
inmemory_max_populate_servers        integer     1
inmemory_query                       string      ENABLE
inmemory_size                        big integer 100M
inmemory_trickle_repopulate_servers_ integer     1
percent
optimizer_inmemory_aware             boolean     TRUE

启动IMO特性,需要设置inmemory_size参数,指定可以作为内存中列存的内存区域,该参数为静态参数,需要重启数据库才能使之生效,sga中会分配一部分内存来作为IMO部分存储,Inmemory_max_populate_servers参数用于将数据加载到内存的后台进程数量。

SQL> select * from v$inmemory_area;

POOL                       ALLOC_BYTES USED_BYTES POPULATE_STATUS                CON_ID
-------------------------- ----------- ---------- -------------------------- ----------
1MB POOL                      82837504    4194304 DONE                                0
64KB POOL                      4194304     131072 DONE                                0

SQL> select * from t_inmemory;

728520 rows selected.

Elapsed: 00:00:09.99

Execution Plan
----------------------------------------------------------
Plan hash value: 2996090576

-----------------------------------------------------------------------------------------
| Id  | Operation                  | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |            | 91065 |     9M|    20  (20)| 00:00:01 |
|   1 |  TABLE ACCESS FULL         | T_INMEMORY | 91065 |     9M|    20  (20)| 00:00:01 |
-----------------------------------------------------------------------------------------

Statistics
----------------------------------------------------------
          9  recursive calls
          0  db block gets
      60188  consistent gets
          0  physical reads
          0  redo size
   40118128  bytes sent via SQL*Net to client
     534788  bytes received via SQL*Net from client
      48569  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
     728520  rows processed

在没有将表T_INMEMORY加载到INMEMOYR中之前,消耗逻辑读要60188,INMEMORY_AREA空间没有使用

SQL> alter table t_inmemory inmemory;

Table altered.

SQL> select * from v$inmemory_area;

POOL                       ALLOC_BYTES USED_BYTES POPULATE_STATUS                CON_ID
-------------------------- ----------- ---------- -------------------------- ----------
1MB POOL                      82837504    4194304 DONE                                0
64KB POOL                      4194304     131072 DONE                                0
将表T_INMEMORY加载到INMEMORY POOL中,此时在没有对表进行查询之前,INMEMORY_AREA pool的空间是没有被使用的

表加载到INMEMORY_AREA pool中后,第一次查询T_INMEMORY表:

SQL> select * from t_inmemory;

728520 rows selected.

Elapsed: 00:00:09.99

Execution Plan
----------------------------------------------------------
Plan hash value: 2996090576

-----------------------------------------------------------------------------------------
| Id  | Operation                  | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |            | 91065 |     9M|    20  (20)| 00:00:01 |
|   1 |  TABLE ACCESS INMEMORY FULL| T_INMEMORY | 91065 |     9M|    20  (20)| 00:00:01 |
-----------------------------------------------------------------------------------------

Statistics
----------------------------------------------------------
          9  recursive calls
          0  db block gets
      60188  consistent gets
          0  physical reads
          0  redo size
   40118128  bytes sent via SQL*Net to client
     534788  bytes received via SQL*Net from client
      48569  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
     728520  rows processed
执行计划出现了变化,新增加了INMEMORY选项,此时逻辑读依然是60188,但是INMEMORY_POOL出现了变化,USED_BYTES增加

SQL> select * from v$inmemory_area;

POOL                       ALLOC_BYTES USED_BYTES POPULATE_STATUS                CON_ID
-------------------------- ----------- ---------- -------------------------- ----------
1MB POOL                      82837504   18874368 DONE                                0
64KB POOL                      4194304     327680 DONE                                0
再次查询,发现逻辑读已经大幅度降低,查询时间也降低到了3秒82

SQL> select * from t_inmemory;

728520 rows selected.

Elapsed: 00:00:03.82

Execution Plan
----------------------------------------------------------
Plan hash value: 2996090576

-----------------------------------------------------------------------------------------
| Id  | Operation                  | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |            | 91065 |     9M|    20  (20)| 00:00:01 |
|   1 |  TABLE ACCESS INMEMORY FULL| T_INMEMORY | 91065 |     9M|    20  (20)| 00:00:01 |
-----------------------------------------------------------------------------------------


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         10  consistent gets
          0  physical reads
          0  redo size
   40118128  bytes sent via SQL*Net to client
     534788  bytes received via SQL*Net from client
      48569  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
     728520  rows processed
此时我们查询别的相关的SQL语句,逻辑读大幅度降低
SQL> select count(*) from t_inmemory;

Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
Plan hash value: 2112900194

----------------------------------------------------------------------------------
| Id  | Operation                   | Name       | Rows  | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |            |     1 |    16   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE             |            |     1 |            |          |
|   2 |   TABLE ACCESS INMEMORY FULL| T_INMEMORY | 91065 |    16   (0)| 00:00:01 |
----------------------------------------------------------------------------------


Statistics
----------------------------------------------------------
          5  recursive calls
          0  db block gets
         16  consistent gets
          0  physical reads
          0  redo size
        544  bytes sent via SQL*Net to client
        551  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

而如果我们将表T_INMEMORY移出IN_MEMORY pool中,逻辑读将回归到之前的数据

SQL> select * from v$inmemory_area;

POOL                       ALLOC_BYTES USED_BYTES POPULATE_STATUS                CON_ID
-------------------------- ----------- ---------- -------------------------- ----------
1MB POOL                      82837504    4194304 DONE                                0
64KB POOL                      4194304     131072 DONE                                0

SQL> select * from t_inmemory;

728520 rows selected.

Elapsed: 00:00:04.10

Execution Plan
----------------------------------------------------------
Plan hash value: 2996090576

--------------------------------------------------------------------------------
| Id  | Operation         | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |            | 91065 |     9M|   426   (1)| 00:00:01 |oracle 12c R1 R1
|   1 |  TABLE ACCESS FULL| T_INMEMORY | 91065 |     9M|   426   (1)| 00:00:01 |
--------------------------------------------------------------------------------


Statistics
----------------------------------------------------------
          5  recursive calls
          0  db block gets
      60182  consistent gets
          0  physical reads
          0  redo size
   97202838  bytes sent via SQL*Net to client
     534788  bytes received via SQL*Net from client
      48569  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
     728520  rows processed

About xiaoyu

xiaoyu,享受数据库带给xiaoyu的乐趣! 13439818916@163.com 欢迎邮件联系讨论
This entry was posted in oracle, sql tuning and troubleshooting. Bookmark the permalink.