カタカタブログ

SIerで働くITエンジニアがカタカタした記録を残す技術ブログ。Java, Oracle Database, Linuxが中心です。たまに数学やデータ分析なども。

Oracle Database 12c (12.1.0.2.0) で遊んでみた(その3) 〜インメモリ有効化〜

前回、前々回とOracle Database 12cの構築まわりをやってきた。

Oracle Database 12cからインメモリオプション(In-Memory Option)がついたと話題になっていたので試してみる。まず、機能を有効化し、テーブル検索時の実行計画にインメモリの計画が表示されることを確認するところまで行う。

テスト用スキーマ準備

まず、インメモリ用のスキーマを整理する。前回testというユーザを作ったが、データを入れることを何も考慮していなかったので表領域周りも考慮して再作成する。

PDB用の表領域を作成

$ sqlplus / as sysdba
SQL> alter session set container=pdbo12c;
SQL> create tablespace pdb01 datafile '/u01/app/oracle12c/oradata/orcl/pdbo12c/pdb01.dbf' size 100M autoextend on;

testユーザを再作成。デフォルト表領域をpdb01にし、必要なシステム権限を付与。

SQL> drop user test;
SQL> create user test identified by test default tablespace pdb01;
SQL> grant connect, resource to test;
SQL> grant unlimited tablespace to test;

作成したスキーマにテストテーブルを作成

$ sqlplus test/test@pdb
SQL> create table testtbl(id number, value varchar2(255));

いちおうデータも入れておく。

SQL> insert into testtbl(id,value) values (1, 'abc');
1 row created.
SQL> commit;
Commit complete.

インメモリ有効化

インメモリオプション自体はデフォルトで有効になっているが、機能を使うためには以下の設定を行う必要がある。

  • テーブルごとにインメモリを有効化する
  • 初期化パラメータでDBのインメモリ領域を確保する

テストテーブルのインメモリ有効化するには以下のようにalter文を実行する

SQL> alter table testtbl inmemory;

Table altered.

初期化パラメータでDBのINMEMORY_SIZEを確保する

まず、インメモリ関連のパラメータを確認しておく

SQL> show parameter inmemory;

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

確かにinmeory_sizeが0になっているので、このままだとインメモリが使われない。
適当に、inmemory_sizeを512MBにしてみる。

SQL> alter system set inmemory_size=512M scope=spfile;
System altered.

静的なパラメータなので、DB再起動が必要。

SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORA-00838: Specified value of MEMORY_TARGET is too small, needs to be at least 888M

しまった!メモリ(MEMORY_TARGET)が少なすぎて上がらないとエラーが出た。。どうやらインメモリの領域はSGA領域のメモリ領域をDBバッファやらのメモリ領域と分け合うらしい。なので、そもそもMEMORY_TARGET値はインメモリで確保したい領域を十分確保できるサイズに設定してやる必要がある。
親切にも最低888Mは必要!と出ているので、この数値に従ってMEMORY_TARGETを拡張することにする。

メモリ関連のパラメータ設定

DBが起動しない状態だと初期化パラメータの変更もできないので、まずpfileを作ってDBを元のパラメータで起動する。
spfileとpfileのパスを確認しておく。

$ ls -l /u01/app/oracle12c/product/12.1.0/dbhome_1/dbs/spfileo12c.ora
-rw-r-----. 1 oracle oinstall 3584 12月 30 10:51 2014 /u01/app/oracle12c/product/12.1.0/dbhome_1/dbs/spfileo12c.ora
$ ls -l /u01/app/oracle12c/product/12.1.0/dbhome_1/dbs/init.ora
-rw-r--r--. 1 oracle oinstall 2992  2月  3 08:24 2012 /u01/app/oracle12c/product/12.1.0/dbhome_1/dbs/init.ora

一時的なpfileを作成する

SQL> create pfile='/u01/app/oracle12c/product/12.1.0/dbhome_1/dbs/ptemp.ora' from spfile='/u01/app/oracle12c/product/12.1.0/dbhome_1/dbs/spfileo12c.ora';

File created.

作成したpfileを修正するし、インメモリ設定の箇所をいったん削除して元に戻す。

$ vi /u01/app/oracle12c/product/12.1.0/dbhome_1/dbs/ptemp.ora
以下の行を削除する。
*.inmemory_size=536870912

修正したpfileを指定してDBを起動する

SQL> startup pfile='/u01/app/oracle12c/product/12.1.0/dbhome_1/dbs/ptemp.ora'
ORACLE instance started.
Total System Global Area  792723456 bytes
Fixed Size     2929400 bytes
Variable Size   545262856 bytes
Database Buffers   239075328 bytes
Redo Buffers     5455872 bytes
Database mounted.
Database opened.

この状態のpfileからspfileに戻しておく

SQL> create spfile='/u01/app/oracle12c/product/12.1.0/dbhome_1/dbs/spfileo12c.ora' from pfile='/u01/app/oracle12c/product/12.1.0/dbhome_1/dbs/ptemp.ora';

File created.

DBを普通に再起動する

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.
Total System Global Area  792723456 bytes
Fixed Size     2929400 bytes
Variable Size   545262856 bytes
Database Buffers   239075328 bytes
Redo Buffers     5455872 bytes
Database mounted.
Database opened.

これでインメモリ変更前の、正しく起動する状態に戻った!

MEMORY_TARGETを888Mに、INMEMORY_SIZEを512Mに変更して、DBを再起動する。

SQL> alter system set memory_target=888M scope=spfile;

System altered.

SQL> alter system set inmemory_size=512M scope=spfile;
System altered.

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.

Total System Global Area  931135488 bytes
Fixed Size     2930992 bytes
Variable Size   339740368 bytes
Database Buffers   46137344 bytes
Redo Buffers     5455872 bytes
In-Memory Area   536870912 bytes
Database mounted.
Database opened.

今度は成功!In-Memory Areaも確保されていることが分かる。

実行計画確認

これでインメモリの設定が有効になったので、フルスキャンのときにINMEMORYという実行計画が出るはず。
まずPDBを起動する。

SQL> alter session set container=pdbo12c;
SQL> startup
SQL> exit

PDBに接続し、テストテーブルへのselect文の実行計画を見てみる。

$ sqlplus test/test@pdb
SQL> explain plan for select * from testtbl;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 294188877
--------------------------------------------------------------------------------
------
| Id  | Operation   | Name    | Rows  | Bytes | Cost (%CPU)| Time
     |
--------------------------------------------------------------------------------
------
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |     |   1 | 142 |   1   (0)| 00:0
0:01 |
|   1TABLE ACCESS INMEMORY FULL| TESTTBL |   1 | 142 |   1   (0)| 00:0
0:01 |
--------------------------------------------------------------------------------
------
Note
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
-----
   - dynamic statistics used: dynamic sampling (level=2)
12 rows selected.

TABLE ACCESS INMEORY FULLとなっており、フルスキャンの際にインメモリ機能を使っているよう!

まとめ

インメモリの機能を使うためには、以下の2つの設定が必要。

  • テーブル個別にインメモリ有効化する
  • DB全体でインメモリ領域(INMEMORY_SIZE)を確保する

ただし、INMEMORY_SIZEはSGA領域から割り当てるのでMEMORY_TARGETを十分なサイズにして確保しておく必要がある。

とりあえずインメモリ機能を使うところまではできたので、性能比較とかやってみたい。今回はここまで!

関連記事