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中.