パラレル実行は深く複雑なトピックであり、並行操作の仕組みを正確に理解し、その能力をより大きく発揮するためには、一定の学習段階を経る必要があります。初心者がパラレル実行の要点を迅速に把握できるように、OceanBaseデータベースV3.1以降では、入門実践ガイドを提供しています。本記事で提供されているパラメータは最適な選択肢とは限りませんが、ほとんどの不良状態を効果的に回避し、初心者がパラレル実行機能をより容易に適用できるようにします。
環境の初期設定
APテナントで設定します:
/* MySQL */
SET GLOBAL parallel_servers_target = MIN_CPU * 20;
/* Oracle */
ALTER SYSTEM SET parallel_servers_target = MIN_CPU * 20;
ここで、MIN_CPU はCPUスペックの下限を表します。各Server上のパラレルクエリキュー条件の設定に関する詳細は、parallel_servers_targetを参照してください。
統計情報の収集
V3.x系では統計情報の収集はマージ処理と結びついているため、データをインポートした後、統計情報の収集を保証するには、一度のマージ処理を開始する必要があります。
V4.x系では、データをインポートした後、DBMS統計情報パッケージを直接呼び出して統計情報を収集できます。
統計情報の詳細については、統計情報の概要を参照してください。
Hintの設定
各SQLの並列度(DOP)は、物理CPU数の1.5倍を超えないように設定してください。 一般的に、複数のSQLが並行して実行されていない場合、単一のSQLの並列度はCPU数に設定できます。例えば、システムの物理CPU数が32の場合、Hintは/*+ PARALLEL(32) */に設定します。
パフォーマンスチューニング
top -Hを使用してテナントのCPU使用状況を確認します。- 単一SQLのパフォーマンスが期待に達していない場合、
sql_plan_monitorを使用してパフォーマンスレポートを取得します。
-- open_dt はオペレータがOpenからCloseまでの時間間隔を表します
-- row_dt はオペレータが最初の行を吐き出してから、OB_ITER_ENDを吐き出すまでの時間間隔を表します
-- 値がNULLの場合、最初の行を吐き出したことがないか、OB_ITER_ENDを吐き出したことがないことを意味します
-- スローSQLにHintを追加してください: /*+ monitor */
-- Hintを追加した後のスローSQLを実行すると、Trace_idが得られます。以下のYxxxxxxxxxに置き換えて、以下のSQLを実行します
-- MySQLテナント:
-- まとめ:
SELECT op_id, op, rows, rescan, threads, (close_time - open_time) open_dt, (last_row_eof_time-first_row_time) row_dt, open_time, close_time, first_row_time, last_row_eof_time FROM
(
select plan_line_id op_id, concat(lpad('', plan_depth, ' '), plan_operation) op, sum(output_rows) rows, sum(STARTS) rescan, min(first_refresh_time) open_time, max(last_refresh_time) close_time, min(first_change_time) first_row_time, max(last_change_time) last_row_eof_time, count(1) threads from oceanbase.gv$sql_plan_monitor where trace_id = 'Yxxxxxxxxx' group by plan_line_id, plan_operation order by plan_line_id
) a;
-- 詳細
SELECT op_id, thread, op, rows, rescan, (close_time - open_time) open_dt, (last_row_eof_time-first_row_time) row_dt, open_time, close_time, first_row_time, last_row_eof_time FROM
(
select plan_line_id op_id, PROCESS_NAME thread, concat(lpad('', plan_depth, ' '), plan_operation) op, output_rows rows, STARTS rescan, first_refresh_time open_time, last_refresh_time close_time, first_change_time first_row_time, last_change_time last_row_eof_time from oceanbase.gv$sql_plan_monitor where trace_id = 'Yxxxxxxxxx' order by plan_line_id, PROCESS_NAME
) a;
-- Oracleテナント:
--説明:open_dtはオペレータがOpenからCloseまでの時間間隔を表します。
--説明:row_dtはオペレータが最初の行を吐き出してからOB_ITER_ENDを吐き出すまでの時間間隔を表します。
--説明:値がNULLの場合、最初の行をハイライトしたことがないか、OB_ITER_ENDをハイライトしたことがないことを意味します。
-- 合計
SELECT op_id, op, output_rows, rescan,threads ,(close_time - open_time) open_dt, (last_row_eof_time-first_row_time) row_dt, open_time, close_time, first_row_time, last_row_eof_time FROM
(
select plan_line_id op_id, concat(lpad(' ', max(plan_depth), ' '), plan_operation) op, sum(output_rows) output_rows, sum(STARTS) rescan, min(first_refresh_time) open_time, max(last_refresh_time) close_time, min(first_change_time) first_row_time, max(last_change_time) last_row_eof_time, count(1) threads from sys.gv$sql_plan_monitor where trace_id = 'Yxxxxxxxxx' group by plan_line_id, plan_operation,plan_depth order by plan_line_id
) a;
-- 詳細
SELECT op_id, thread, op, output_rows, rescan, (close_time - open_time) open_dt, (last_row_eof_time-first_row_time) row_dt, open_time, close_time, first_row_time, last_row_eof_time FROM
(
select plan_line_id op_id, PROCESS_NAME thread, concat(lpad(' ', plan_depth, ' '), plan_operation) op, output_rows, STARTS rescan, first_refresh_time open_time, last_refresh_time close_time, first_change_time first_row_time, last_change_time last_row_eof_time from sys.gv$sql_plan_monitor where trace_id = 'Yxxxxxxxxx' order by plan_line_id, process_name
) a;
よくある質問
Queryのクエリパフォーマンスが期待通りにならず、CPUがフル活用されていない?
show variables like 'parallel_servers_targetを実行し、target値がMIN_CPU* 20以上であることを確認してください。PDMLのパフォーマンスが期待通りにならない?
explain extendedを使用してPDMLを説明し、計画がPDMLを経由していることを確認してください。PDMLを経由していない場合、計画の最下部のNoteフィールドにその理由が記載されています。一般的には、変更されたテーブルにトリガー、外部キー、local unique indexなどが含まれているためです。DISTRIBUTED INSERT、DISTRIBUTED UPDATE、DISTRIBUTED DELETEなどの文字が表示された場合、PDMLを経由していないことを意味します。PDMLがタイムアウトし、内部ログに
-4138 OB_SNAPSHOT_DISCARDEDエラーが表示される?undo_retentionパラメータをPDMLの最大実行時間以上に設定してください。デフォルト値はわずか30分であり、PDMLの実行時間が30分を超えるとこの問題が発生し、実行が終了してタイムアウトするまで再試行されます。OceanBase V4.1以降ではPDMLタイムアウトの問題は発生しなくなっており、手動で
undo_retentionを設定する必要はありません。業務上、一切の変更ができない場合、業務SQLを並列化する方法は?
OBProxyでは、Webインターフェース上で接続設定を変更し、並列処理を有効にすることができます。例えば、読み書き分離接続において、すべてのSQLの並列度を2に設定します。