データブロックの効率的な使用(1) --- データブロックのチューニング

  • データブロックのサイズ大小
    • 小さいデータブロックサイズは一行のデータ量が少なくランダムアクセスが多いOLTP系向き
    • 大きいデータブロックサイズは大量のデータに順次アクセスするDSS向き

  説明
ブロック競合 ○少 ×大 データブロックあたりの行数が多いほど競合が発生しやすい
DBBC ○少 ×多 ランダムアクセスする場合、特に注意
ブロック効率 ×悪 ○良 ブロックヘッダのサイズは同じなので、ブロックサイズが小さいほど効率悪い
索引の階層 ×深 ○浅 一つのデータブロックに入らなかったらリーフノードが分割されるので、階層が深くなってしまう

  • 非標準データブロックサイズを使う
    • DB_nK_CACHE_SIZE(n=2,4,8,16,32)パラメータを使用して、nKデータ・ブロック用のバッファ・キャッシュを用意する
    • CREATE TABLESPACEコマンドで、BLOCKSIZEオプションを指定した表領域を作成する
    • CREATE TABLEコマンドで、TABLESPACEオプションを使用して作成した表領域に表が格納されるようにする
  • 最高水位標(HWM)
    • 未使用ブロックと使用済み(過去に1回でも使用されたことのある)ブロックの境目を示す
    • セグメントヘッダーで管理
    • 使用されるのは...
      • 全表走査:HWM以下のデータブロックをすべて読み込む(HWM以下の使用率が悪いと、全表走査効率が悪くなる)
      • ダイレクトパスロード:HWMより上のブロックを使用してロードする
    • HWMはTRUNCATEでリセットされるが、DELETE文ではリセットされない
  • HWMを確認する
    • ANALYZEコマンド&DBA_TABLESビュー
    • DBMS_SPACEパッケージを使用
  • PCTFREEとPCTUSED
    • パーセンテージで指定。二つを足して100以下になるように設定
    • PCTFREE
      • UPDATEで使用するためにとっておく領域の設定
      • ブロック内の空き領域がこの値を下回ると空きリストからはずされ、INSERTなどはできなくなる
      • 参照系ならごく小さくてよい(そんなスペース使うことが無い)
    • PCTUSED
      • このブロックにINSERT可能になる閾値の設定
      • ブロック内の使用領域がこの値を下回ると空きリストに登録され、このブロックにINSERTできるようになる
      • デフォルトは40
      • 行が頻繁に削除される場合には大きく設定する(使用効率が上がる)
      • ただし、大きくすると空きリストのメンテナンスが増えるので、パフォーマンスは落ちる
  • 行連鎖/行移行
    • 行連鎖
      • データが1つのデータブロックに入りきらず、複数のデータブロックにまたがって格納される現象
      • 原因は設計ミス(データブロックが小さすぎる)ことが多い
      • 解消するにはブロックサイズを大きくして作り直すしかない(最悪、DB再構築)
    • 行移行
      • UPDATE文によって行データが大きくなり、データブロック内のある行データが別のデータブロックに移動した状態
      • 原因はPCTFREE設定ミス
      • 解消するにはPCTFREEを大きくする
    • どちらも索引走査の場合、移行先を示すポインタ(ROWID)は最初のデータブロックにあるため、移行先のデータを読むには更にそのROWIDが示すデータブロックを探して拾ってくる必要があり、パフォーマンスが落ちる。
  • 行連鎖/行移行の検出
    • v$sysstatやSTATSPACKを使用して、table fetch continued rowシステム統計を確認(行数)
    • ANALYZEコマンドを実行後、DBA_TABLES.CHAIN_CNT列を確認(表ごとの行数)
    • ANALYZE...LIST CHAINED ROWSコマンド(ROWIDを取得できる)
SQL> select * from v$sysstat
     where name='table fetch continued row' ;

STATISTIC# NAME                            CLASS  VALUE
---------- ------------------------------ ------ ------
       194 table fetch continued row          64     79
  • 表の再構築
    • HWM以下のブロックの空き領域が多い場合や行移行が起こっている場合は、表の再構築を検討
      • エクスポート/インポートを使用して再作成
      • ALTER TABLE ... MOVEコマンドで表を移動(表に付属する索引は別途再構築が必要)
      • ALTER TABLE .. DEALLOCATE UNUSEDコマンドを使用して最高水位標より上のエクステントを開放
      • ANALYZE...LIST CHAINED ROWSコマンドで検出した行を一時表にコピーしてまた戻す
  • 自動セグメント領域管理
    • そんなこんなで、データブロックの管理は面倒なので、9iからはOracleに管理をおまかせ
    • 自動管理してくれるのは...
      • PCTUSED
      • FREELISTS
      • FREELISTS GROUP
    • PCTFREEは管理してくれません
    • ローカル管理表領域でのみ使用することができる
    • create tablespace ... segment space management auto