2.

共有プール

編集

Oracleの共有プールの記事です。

共有プールとは解析済みのSQLのデータをキャッシュしておく領域です。

SQLの実行計画を保持しておくことで、同じSQLが発行された際の解析処理を省くことが出来ます。SGA(システムグローバル領域)を構成する主要メモリのひとつで、Oracleのパフォーマンスに直結する重要な領域です。

共有プールの構成

共有プールは大きく2つのキャッシュから構成されます。

領域役割
ライブラリキャッシュ解析済みSQL文、実行計画、PL/SQLプログラムをキャッシュ
データディクショナリキャッシュ(ローキャッシュ)テーブル定義・ユーザー権限・統計情報など、データディクショナリ情報をキャッシュ

SQL実行時の流れ

  1. クライアントから SQL が送られる
  2. SQLハッシュ値を計算 → 共有プールに同じSQLがあるか確認
  3. あれば(ソフトパース): 既存の実行計画を再利用
  4. なければ(ハードパース): 構文解析・最適化を実施し、結果を共有プールに格納
  5. 実行

ハードパースは重いため、同じSQLは共有プールから再利用されるのがパフォーマンスの肝になります。

共有プールサイズの確認

-- 設定値
SQL> SHOW PARAMETER shared_pool_size;

-- 現在の使用状況
SQL> SELECT * FROM v$sgastat
        WHERE pool = 'shared pool';

-- ライブラリキャッシュのヒット率
SQL> SELECT namespace, pins, pinhits,
            ROUND(pinhits/pins*100, 2) AS hit_ratio
     FROM v$librarycache;

サイズ調整

-- 共有プールサイズを変更
SQL> ALTER SYSTEM SET SHARED_POOL_SIZE = 512M SCOPE = BOTH;

-- 自動メモリ管理を使用している場合は
SQL> ALTER SYSTEM SET MEMORY_TARGET = 4G SCOPE = BOTH;

バインド変数の重要性

共有プールの有効活用には、バインド変数の使用が必須です。リテラル値を埋め込んだSQLはハッシュ値が変わり、毎回ハードパースが発生します。

-- NG: ID毎にハードパースが走る
SELECT * FROM users WHERE id = 1;
SELECT * FROM users WHERE id = 2;
SELECT * FROM users WHERE id = 3;

-- OK: 同じSQLとして共有プールヒット
SELECT * FROM users WHERE id = :id;

共有プールがあふれる症状と対処

  • ORA-04031: shared memory pool で共有メモリ確保不可 — サイズ不足/フラグメンテーション
  • 対処1: SHARED_POOL_SIZE を大きく
  • 対処2: SHARED_POOL_RESERVED_SIZE を増やす
  • 対処3: 共有プールをフラッシュ ALTER SYSTEM FLUSH SHARED_POOL;(一時対処)
  • 根本対処: バインド変数を使う、無駄に大量のSQLバリエーションを減らす

関連

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. データベースバッファキャッシュ
  2. 共有プール
  3. REDOログバッファ
  4. ラージプール