1. 程式人生 > >12c新特性-感受ORACLE 12C IN_MEMORY效能威力

12c新特性-感受ORACLE 12C IN_MEMORY效能威力

感受ORACLE 12C IN_MEMORY效能威力

      oracle 12C in_memory(簡稱IM)對資料庫效能的提升是巨大的,最重要的一點是這一切

 對應用程式是透明的。首先我們來看看實驗中IM的相關引數設定

使用imemory特性的前提,要設定這兩個引數

SQL>alter system set  inmemory_max_populate_servers=2 scope=spfile;

SQL>alter system set inmemory_size=100M scope=spfile;(這個引數設定的大小最小為100M)

SQL> show parameter inmemory;

 NAME                                 TYPE        VALUE

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

 inmemory_clause_default              string

 inmemory_force                       string      DEFAULT

 inmemory_max_populate_servers        integer     2

 inmemory_query                       string      ENABLE

 inmemory_size                        big integer 100M

 inmemory_trickle_repopulate_servers_ integer     1

 percent

 optimizer_inmemory_aware             boolean     TRUE

建立一個普通使用者,建立一個表資料來自dba_objects;

 SQL> create user c##frank identified by frank;

 User created.

 SQL> grant connect,resource,unlimited tablespace to c##frank;

 Grant succeeded.

 SQL> create table c##frank.t1 as select * from dba_objects;

 Table created.

把使用者表放到IM中.

SQL> alter table t1 c##frank.inmemory;

 Table altered.

收集一下統計息.

SQL> exec dbms_stats.gather_table_stats('C##FRANK','T1');

 PL/SQL procedure successfully completed.

 SQL> set autotrace on;

 SQL> select count(object_id) from c##frank.t1;

 COUNT(OBJECT_ID)

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

            90905

 Execution Plan

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

 Plan hash value: 3724264953

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

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

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

 |   0 | SELECT STATEMENT            |      |     1 |     5 |    27   (0)| 00:00:01 |

 |   1 |  SORT AGGREGATE             |      |     1 |     5 |            |          |

 |   2 |   TABLE ACCESS INMEMORY FULL| T1   | 90905 |   443K|    27   (0)| 00:00:01 |

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

 Statistics

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

           0  recursive calls

           0  db block gets

           3  consistent gets

           0  physical reads

           0  redo size

         552  bytes sent via SQL*Net to client

         552  bytes received via SQL*Net from client

           2  SQL*Net roundtrips to/from client

           0  sorts (memory)

           0  sorts (disk)

           1  rows processed

做一個簡單的查詢,可以看出有以下幾點:

1全表掃描多了INMEMORY關健字;

2consistent gets急劇減少,少得有點可憐了,說明對記憶體訪問極少;

3,cost是27相比傳統的查詢,看看in-memory快了多少,使用NO_INMEMORY hint讓optimizer不走in-memory,而走傳統的buffer cache

 SQL> select /*+ NO_INMEMORY */ count(object_id) from t1;

 COUNT(OBJECT_ID)

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

            90905

 Execution Plan

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

 Plan hash value: 3724264953

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

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

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

 |   0 | SELECT STATEMENT   |      |     1 |     5 |   416   (1)| 00:00:01 |

 |   1 |  SORT AGGREGATE    |      |     1 |     5 |            |          |

 |   2 |   TABLE ACCESS FULL| T1   | 90905 |   443K|   416   (1)| 00:00:01 |

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

 Statistics

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

          33  recursive calls

           0  db block gets

        1557  consistent gets

           0  physical reads

           0  redo size

         552  bytes sent via SQL*Net to client

         552  bytes received via SQL*Net from client

           2  SQL*Net roundtrips to/from client

           3  sorts (memory)

           0  sorts (disk)

           1  rows processed

傳統的成本是416,consistent gets是1557,相比in-memory,訪問資料大量增加.這是由於是傳統是儲存的是行式,而in-memory存放的是列式.速度快了非常多.有人可能會問,這裡選擇是單列,如果是count(*)了,效能還有這麼明顯嗎?好,我們來看例子

SQL> select /*+ NO_INMEMORY */ count(*) from c##frank.t1;

   COUNT(*)

 ----------

      90905

 Execution Plan

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

 Plan hash value: 3724264953

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

 | Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |

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

 |   0 | SELECT STATEMENT   |      |     1 |   426   (1)| 00:00:01 |

 |   1 |  SORT AGGREGATE    |      |     1 |            |          |

 |   2 |   TABLE ACCESS FULL| T1   | 90905 |   426   (1)| 00:00:01 |

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

 Statistics

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

           5  recursive calls

           0  db block gets

        1536  consistent gets

        1527  physical reads

           0  redo size

         544  bytes sent via SQL*Net to client

         552  bytes received via SQL*Net from client

           2  SQL*Net roundtrips to/from client

           0  sorts (memory)

           0  sorts (disk)

           1  rows processed

在實驗中還產生了物理讀.再來看看in-memory的count(*)

 SQL> select /*+ INMEMORY */ count(*) from c##frank.t1;

   COUNT(*)

 ----------

      90905

 Execution Plan

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

 Plan hash value: 3724264953

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

 | Id  | Operation                   | Name | Rows  | Cost (%CPU)| Time     |

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

 |   0 | SELECT STATEMENT            |      |     1 |    27   (0)| 00:00:01 |

 |   1 |  SORT AGGREGATE             |      |     1 |            |          |

 |   2 |   TABLE ACCESS INMEMORY FULL| T1   | 90905 |    27   (0)| 00:00:01 |

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

 Statistics

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

           0  recursive calls

           0  db block gets

           3  consistent gets

           0  physical reads

           0  redo size

         544  bytes sent via SQL*Net to client

         552  bytes received via SQL*Net from client

           2  SQL*Net roundtrips to/from client

           0  sorts (memory)

           0  sorts (disk)

           1  rows processed

即使count(*),in-memory也和原來一樣,快上很多倍.估計看到這樣一對比很多人都已經坐不住了.

比如手動把表放到in-memory area中

SQL> create table t1(a int,b int);

Table created.

SQL> alter table t1 inmemory;

Table altered.

取消表在inmemory中存放

SQL> alter table t1 no inmemory;                             

Table altered.

還可以在欄位級定義哪一欄放到 in-memory area中

SQL> alter table t1 inmemory;

Table altered.

SQL>  alter table t1 inmemory (a) no inmemory (b);

Table altered.

先定義整個表存放在in memory中,才能再定義某個欄位存放在in memory中.