Oracleデータベースの並列処理:テーブルとインデックスの最適化戦略

Oracleの並列処理基礎概念

Oracleデータベースでは、テーブルやインデックスに並列度を設定することで、複数のCPUリソースを同時に活用し、大規模なデータ操作のパフォーマンスを向上させることができます。DBA_TABLESやDBA_INDEXSデータディクショナリのDEGREEフィールドが、この並列度を示します。

現在の並列度設定の確認方法

-- 全テーブルの並列度を確認
SELECT table_name, degree FROM user_tables;

-- 並列度が2以上のテーブルを抽出
SELECT owner, table_name, degree 
FROM dba_tables 
WHERE degree > 1;

-- 並列度が設定されたインデックスの一覧
SELECT owner, index_name, degree 
FROM dba_indexes 
WHERE degree > 1;

並列度の設定には注意が必要です。高すぎる並列度はDirect Path Read待機を引き起こす可能性があり、推奨される並列度は「CPU数 × 2~4」です。

テーブル並列度の変更方法

-- 特定の並列度を指定
ALTER TABLE employee_data PARALLEL(DEGREE 4);

-- デフォルトの並列度に設定
ALTER TABLE employee_data PARALLEL;

-- 並列処理を無効化
ALTER TABLE employee_data NOPARALLEL;

SQL文での並列処理活用

クエリヒントを使用した並列実行

-- 並列度8で実行
SELECT /*+ PARALLEL(emp_tbl, 8) */ 
       department_id, COUNT(*) AS emp_count,
       AVG(salary) AS avg_salary
FROM employee_data emp_tbl
WHERE hire_date > TO_DATE('2020-01-01', 'YYYY-MM-DD')
GROUP BY department_id;

-- 自動並列度で実行
SELECT /*+ PARALLEL(AUTO) */ 
       product_category, SUM(revenue)
FROM sales_records
GROUP BY product_category;

-- 並列処理を明示的に無効化
SELECT /*+ NO_PARALLEL */ 
       customer_name, order_date
FROM customer_orders
WHERE status = 'PENDING';

並列処理の適用場面

推奨シナリオ:

  • 大規模テーブルのスキャン操作
  • テーブル間のJOIN処理
  • パーティションインデックスの検索
  • 一括インデックス作成・再構築
  • 大量データのINSERT/UPDATE/DELETE

非推奨シナリオ:

  • 短時間で完了する小規模クエリ
  • OLTP環境の頻繁なDML操作

DML文での並列処理設定

並列DML操作を有効にするには、セッションレベルで設定が必要です:

-- 並列DMLを有効化
ALTER SESSION ENABLE PARALLEL DML;

-- 並列INSERT例
INSERT /*+ PARALLEL(target_tbl, 4) */ 
INTO target_tbl
SELECT * FROM source_tbl;

-- 並列UPDATE例
UPDATE /*+ PARALLEL(employee_data, 4) */ 
SET salary = salary * 1.1
WHERE department_id IN (10, 20, 30);

インデックス作成時の並列処理

並列インデックスの作成と管理

-- 並列度6でインデックスを作成
CREATE INDEX idx_emp_salary 
ON employee_data(salary, department_id) 
PARALLEL 6;

-- インデックスの並列度を確認
SELECT index_name, degree 
FROM user_indexes 
WHERE table_name = 'EMPLOYEE_DATA';

-- インデックスの並列度を変更
ALTER INDEX idx_emp_salary PARALLEL(DEGREE 2);

-- インデックスの並列処理を無効化
ALTER INDEX idx_emp_salary NOPARALLEL;

注意:インデックス作成後に並列度をリセットしないと、通常のクエリでも不要な並列処理が発生し、システムリソースを消費する可能性があります。

インデックス使用の強制指定

特定インデックスを明示的に使用する方法

-- 特定インデックスを指定してクエリ実行
SELECT /*+ INDEX(emp_tbl idx_emp_dept_salary) */ 
       emp_id, emp_name, salary
FROM employee_data emp_tbl
WHERE department_id = 50
  AND salary > 50000;

-- 複数のインデックスヒントを組み合わせ
SELECT /*+ INDEX(e idx_emp_name) INDEX(d idx_dept_location) */ 
       e.emp_name, d.location_name
FROM employees e, departments d
WHERE e.dept_id = d.dept_id
  AND e.hire_date > SYSDATE - 365;

11g以降の並列処理ヒント拡張機能

Oracle 11gから導入された高度な並列処理制御機能:

-- 自動並列度計算(最低1)
SELECT /*+ PARALLEL(AUTO) */ column_list FROM table_name;

-- オブジェクトの設定を強制使用
SELECT /*+ PARALLEL(MANUAL) */ column_list FROM table_name;

-- 常に並列実行(最低2)
SELECT /*+ PARALLEL(DEFAULT) */ column_list FROM table_name;

-- 固定並列度指定
SELECT /*+ PARALLEL(6) */ column_list FROM table_name;

パフォーマンス監視のベストプラクティス

-- 並列クエリの実行統計を確認
SELECT sql_id, operation, options, degree
FROM v$sql_plan
WHERE operation LIKE 'PX%';

-- 並列処理の待機イベントを監視
SELECT event, total_waits, time_waited
FROM v$system_event
WHERE event LIKE 'PX%';

タグ: Oracle 並列処理 データベース最適化 インデックス SQLチューニング

5月17日 19:23 投稿