マテリアライズドビューを活用できるようになると動作の高速なビューを扱えるようになります。ここではマテリアライズドビューのメリットとデメリットや使い方をご紹介します。
マテリアライズドビューとは
マテリアライズドビューとはデータの実体を持ったビューのことです。
ビューは仮想テーブルであり実際のデータを持っていませんが、マテリアライズドビューはSQLで取得したデータを使い、即席のテーブルを作成できる仕組みです。これをデータの永続化と言います。
ビューと異なる点はリフレッシュという処理が必要になる点です。マテリアライズドビューはデータの実体を持つので定期的に最新のデータに更新する必要があります。これがリフレッシュです。
基本的にマテリアライズドビューはOracle内で一つのテーブルとして扱われるので、テーブルにできる操作の大半はマテリアライズドビューにも適用できます。
マテリアライズドビューのメリット
マテリアライズドビューを選択することは以下のメリットがあります。
高速なビューを扱える
通常のビューは実体データを持っていないので、ビューが呼び出される度にビューのSQLでデータを取得する必要があります。
マテリアライズドビューの場合は実体のデータを持っているので一々データを取得する必要がなく、その分SQLの高速化が実現できます。
ビューのSQLが複雑、または集計処理が入っている等でデータの取得に時間がかかる場合はマテリアライズドビューの導入を検討するタイミングだと言えます。
主キーやインデックスを定義できる
マテリアライズドビューは通常のビューと異なり主キーを定義できます。主キーを定義することでデータ検索の高速化とデータ重複を防ぐことができます。
またインデックスを作成することもできます。インデックスとはテーブルからデータを効率良く探すために作成する索引のことです。
通常のビューにはインデックスを作成できませんが、マテリアライズドビューには索引を作成できるので、より高速にデータにアクセス可能です。
マテリアライズドビューのデメリット
メリットの一方で、マテリアライズドビューにはデメリットもあります。
リフレッシュが必要
マテリアライズドビューはデータの実体があるので、常に最新のデータが取得できるわけではなく、最新データを取得する場合はリフレッシュ処理をする必要があります。
リフレッシュを怠ると旧データを取得してしまい、元になるテーブルのデータと齟齬が生じ、バグの原因になり得ます。
通常のテーブル同様ストレージを消費する
マテリアライズドビューは通常のテーブルと同じような扱いができ非常に便利ですが、反面テーブルと同様にストレージ容量を消費してしまいます。
AWSのRDS等クラウドのRDBMSを使用している場合はストレージの圧迫がそのまま予算増に繋がる危険性があります。
マテリアライズドビューの作成方法
ここからは実際にマテリアライズドビューを作ってみましょう。
マテリアライズドビューの作成はCREATE MATERIALIZED VIEW文を使います。
今回はこれらのテーブルを元テーブルとして使用します。
EMPLOYEES
DEPARTMENT
BRANCH
CREATE MATERIALIZED VIEW EMPLOYEE_M_VIEW AS
SELECT
E.ID
, E.NAME
, B.NAME AS BRANCH_NAME
, D.NAME AS DEPARTMENT_NAME
FROM
EMPLOYEES E
JOIN BRANCH B ON E.BRANCH_ID = B.ID
JOIN DEPARTMENT D ON E.DEPARTMENT_ID = D.ID
これでマテリアライズビューが作成されました。(余談ですが、マテリアライズドビューには_M_VIEWを付けて命名する場合が多いです)
オブジェクトの種類を確認してみましょう。次のSQLを実行します。
SELECT
OBJECT_NAME,
OBJECT_TYPE
FROM USER_OBJECTS
WHERE OBJECT_NAME = 'EMPLOYEE_M_VIEW'
USER_OBJECTSはORACLEがバックグラウンドで自動的に作成するテーブルで、作成したテーブルやビューなどのオブジェクトが一覧で取得できます。
結果を見てみるとMATERIALIZED VIEWの他にTABLEも作成されています。EMPLOYEE_M_VIEWをSELECTする場合はTABLEが使われるので、oracle内でテーブルとして扱うことができます。
では試しに作成したマテリアライズドビューをSELECTしてみましょう。
SELECT * FROM EMPLOYEE_M_VIEW
正常に作成されているのが分かります。
マテリアライズドビューの削除
削除したい場合はDROP MATERIALIZED VIEW文を使います。
DROP MATERIALIZED VIEW EMPLOYEE_M_VIEW
マテリアライズドビューのリフレッシュ方法
前述した通り、マテリアライズドビューは通常のビューと異なり、リフレッシュを行わないと最新のデータに更新されません。
リフレッシュ方法には手動リフレッシュと自動リフレッシュがあります。
手動リフレッシュ
手動リフレッシュはデフォルトのリフレッシュ方法で、管理者自身でリフレッシュするタイミングを決定できます。
リフレッシュするには次のコマンドを実行します。
exec DBMS_MVIEW.REFRESH(マテリアライズドビュー名,リフレッシュ方法);
リフレッシュ方法には「c」か「f」が入ります。cは完全リフレッシュでfが高速リフレッシュです。
完全リフレッシュはマテリアライズドビューが保持しているデータを一度全て削除してから再度SELECTしてデータを再構築します。
一方高速リフレッシュは更新されたレコードのみリフレッシュします。完全リフレッシュより速くリフレッシュできますが、マテリアライズドビューログを作成したり、SELECT文に制約があるなど完全リフレッシュよりも複雑な条件下でのみ利用可能です。
今回は完全リフレッシュで手動リフレッシュを試してみましょう。
まずDEPARTMENTテーブルの「開発部」を「ソリューション部」に変更します。
UPDATE DEPARTMENT SET NAME = 'ソリューション部' WHERE ID = 2;
SELECT * FROM DEPARTMENT;
この状態でEMPLOYEE_M_VIEWを確認してみましょう。
SELECT * FROM EMPLOYEE_M_VIEW
マテリアライズドビューなので、吉田さんのDEPARTMENT_NAMEが開発部のままになっています。手動リフレッシュした後にもう一度SELECTしてみましょう。
exec DBMS_MVIEW.REFRESH('EMPLOYEE_M_VIEW','c');
無事にリフレッシュされ、DEPARTMENT_NAMEがソリューション部に更新されました。
自動リフレッシュ
自動リフレッシュはあらかじめ決定したタイミングでリフレッシュする方法です。
マテリアライズドビューをCREATEするときにREFON COMMIT句またはSTART WITH句を指定することで自動リフレッシュにできます。
ON COMMITはSELECTで指定しているテーブルが更新された場合にリフレッシュします。一方START WITHはスケジューリングした時間毎にリフレッシュします。試しにON COMMITで自動リフレッシュしてみましょう。ON COMMITは手動リフレッシュと違い様々な制限があります。
具体的には高速リフレッシュの制限がそのままON COMMIT時にも適用されます(なのでON COMMITできる場合は高速リフレッシュができるということです)。
高速リフレッシュの制限は数が多くここでは説明しきれません。Oracleの公式リファレンスを参照してください。ではON COMMITを試してみましょう。
制限を掻い潜るため、簡単なクエリでマテリアライズドビューを作成します。
CREATE MATERIALIZED VIEW CROSS_M_VIEW
REFRESH ON COMMIT AS
SELECT
D.ID AS D_ID,
D.NAME AS D_NAME,
B.ID AS B_ID,
B.NAME AS B_NAME
FROM
DEPARTMENT D,
BRANCH B
部署と支店のテーブルをクロス結合しただけのマテリアライズドビューです。
中身はこうなっています。
ON COMMITを指定しているので、NAMEを更新したタイミングで(正確にはコミットしたタイミングで)CROSS_M_VIEWの中身が変わります。
やってみましょう。
UPDATE DEPARTMENT SET NAME = 'ソリューション部' WHERE ID = 2;
SELECT * FROM CROSS_M_VIEW
自動的に部署名が変わりました。
- カテゴリ:
- キーワード: