データベースリンク(DBLINK)を使用したSQLの動作が遅いと感じていませんか?
Oracle DRIVING_SITE ヒントは、分散データベース環境において「どのサイト(ローカルまたはリモート)でSQLを実行するか」を指定する強力な手段です。
本記事では、DBLINKが遅い 原因の特定から、DRIVING_SITE ヒントを使って処理をリモート側へ寄せ、劇的にパフォーマンスを改善する方法を解説します。大量データをネットワーク越しに全件転送してしまう「無駄」をなくし、最適な実行計画へ導きましょう。
💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?
結論・最短手順(TL;DR)
DBLINK経由の結合処理が遅い場合、まず以下を確認・実施します。
- 実行計画を確認する
- ローカル側で
REMOTE(全件転送)が発生していないか確認。
- ローカル側で
- DRIVING_SITE ヒントを付与する
SELECT /*+ DRIVING_SITE(リモート表の別名) */ ...を追記。
- 効果を測定する
- ネットワーク転送量が減り、応答時間が短縮されたか確認。
DRIVING_SITE とは?(仕組みと基礎)
DBLINKが遅くなる主な原因
通常、Oracleのオプティマイザ(CBO)はコストに基づいて実行場所を決めますが、統計情報の不備や複雑な結合により、「リモート側の大量データを、ローカル側に全件持ってきてから結合する」 という非効率な計画を選択することがあります。これがネットワーク帯域を圧迫し、遅延の原因となります。
DRIVING_SITE の役割
DRIVING_SITE ヒントは、「クエリの実行主体(ドライビングサイト)を指定したテーブルが存在するサイトで行う」 よう強制します。
- ヒントなし(遅い例): リモートの100万件をローカルへ転送 → ローカルでフィルタ → 10件抽出。
- ヒントあり(高速化): リモート側でフィルタ実行 → 結果の10件だけをローカルへ転送。
初心者向けメモ:
「出張料理人(データ転送)」に来てもらうか、「レストラン(リモート)」へ自分が食べに行くかの違いです。材料(データ)が大量にあるなら、レストランへ行ったほうが移動コストは安く済みます。
手順・実装:DRIVING_SITE の使い方
基本的な構文と適用手順です。
基本構文
SELECT /*+ DRIVING_SITE(テーブル別名) */ 列名
FROM ローカル表 A, リモート表@dblink B
WHERE A.ID = B.ID;
※ 注意: テーブルにエイリアス(別名)をつけている場合、ヒント内も必ずエイリアスで指定してください。
適用判断フロー
[現状の遅いSQL]
↓
[実行計画取得 (EXPLAIN PLAN)]
↓
[判断: リモート表へのアクセスが "FULL SCAN" かつ大量転送か?]
├─ No (Indexが効いている) → そのまま、または別の原因を調査
└─ Yes (全件転送されている) → DRIVING_SITE の出番
↓
[ヒント句を追加して実行]
↓
[改善確認]
💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?
実行例:具体的なSQLと改善イメージ
ここでは、ローカルの小規模なマスタ表と、リモートの大規模な売上表を結合するケースを想定します。
前提条件
- ローカル (Site A):
DEPT表(数件・小) - リモート (Site B):
SALES表(数千万件・大・DBLINK名remote_db) - 目的: 特定部署の売上明細を取得する。
1. 対策前のSQL(遅い可能性がある例)
オプティマイザが判断を誤ると、リモートの SALES 全件をネットワーク越しに取得しはじめます。
-- エイリアス s を使用
SELECT d.dname, s.amount
FROM dept d
JOIN sales@remote_db s ON d.deptno = s.deptno
WHERE d.deptno = 10;
2. DRIVING_SITE を適用したSQL(推奨)
リモート側(sales がある側)で結合処理を行わせます。
-- salesテーブルのエイリアス "s" をヒントに指定
SELECT /*+ DRIVING_SITE(s) */
d.dname, s.amount
FROM dept d
JOIN sales@remote_db s ON d.deptno = s.deptno
WHERE d.deptno = 10;
SQLの解説と結果
- /*+ DRIVING_SITE(s) */: オプティマイザに対し、「
s(sales@remote_db) があるサイト(Site B)を実行主体にしなさい」と指示します。 - 動作の変化:
- Oracleはローカルの
deptテーブル(の該当行)を Site B へ送ります。 - Site B 上で
salesテーブルと結合・抽出を行います。 - 結果セットのみを Site A(ローカル)へ返します。
- Oracleはローカルの
- 効果: ネットワークを行き来するデータ量が劇的に削減されます。
トラブルシューティング
ヒントをつけても速くならない、またはエラーになる場合のチェックリストです。
| 原因 | 確認ポイント | 対処法 |
| ヒントが無効 | エイリアスを使っているのに、テーブル名を指定していないか? | FROM tab1 t1 なら DRIVING_SITE(t1) と書く。 |
| 権限エラー | ORA-02019 などの接続エラー | パスワード期限切れやTNS設定を確認。 |
| 逆に遅くなった | ローカル側の表も実は巨大だった | dept も巨大な場合、ローカルデータをリモートへ送るコストが増大する。データ量を見極める。 |
| CBOの無視 | 統計情報が古すぎる | 両サイトの統計情報を取得し直す(DBMS_STATS)。 |
運用・監視・セキュリティ上の注意
メリットとデメリット
- メリット: ネットワーク負荷の低減、ローカルDBのCPU/メモリ負荷の軽減。
- デメリット: リモートDB(Site B)のCPU負荷が上昇する。リモートDBが共有環境の場合、他システムへ影響を与える可能性がある。
注意点:ビュー(VIEW)の使用
リモートテーブルを含むビューに対して DRIVING_SITE を使う場合、ビュー定義の中にヒントを埋め込む必要があるケースがあります。外部からのヒント付与が効きにくい場合があるため、実行計画を必ず確認してください。
リスクと戻し方
- リスク: リモートDBが高負荷になり、リンク先の業務を遅延させる。
- 戻し方: ヒント句
/*+ ... */を削除するだけで、元の挙動(ローカル主導)に戻ります。即時切り戻しが可能です。
FAQ:よくある質問
Q1. INSERT … SELECT 文でも使えますか?
A. 使えますが、注意が必要です。
INSERT INTO local_tab SELECT /*+ DRIVING_SITE(r) */ * FROM remote_tab@dblink r のようなケースでは有効です。ただし、DML(更新系)は分散トランザクション制御が絡むため、単純な参照よりもオーバーヘッドがかかる場合があります。
Q2. 複数のDBLINKがある場合、どこが実行サイトになりますか?
A. ヒントで指定したテーブルが存在するサイトが実行サイトになります。
例えば @link_A と @link_B のテーブルを結合し、DRIVING_SITE(table_at_link_A) を指定すれば、処理は Site A で行われます。Site B のデータは Site A へ転送されます。
Q3. ヒントを指定しても実行計画が変わりません。
A. 構文ミス(エイリアスの不一致)が最も多い原因です。
また、クエリの内容によっては「どうしてもローカルで処理せざるを得ない(例:ローカルにしかない独自関数を使用している等)」場合、オプティマイザがヒントを無視することがあります。
まとめ
DBLINKを含むクエリのパフォーマンスチューニングにおいて、DRIVING_SITE は初手に検討すべき有効な手段です。
- ネットワーク転送量 がボトルネックなら
DRIVING_SITEを疑う。 - 必ず テーブルのエイリアス をヒントに記述する。
- リモート側の負荷 が許容範囲か考慮する。
- 実行計画 で
REMOTEの挙動が変わったか確認する。
まずは開発環境で EXPLAIN PLAN を取得し、データがどこで処理されているかを可視化することから始めてみてください。
[参考]
分散データベース・システムのアプリケーション開発
33.4.3.3 DRIVING_SITEヒントの使用
DRIVING_SITEヒントを使用すると、問合せが実行されるサイトを指定できます。コストベース最適化によって実行が行われる場所を決定することをお薦めしますが、オプティマイザを無効にする場合は、手動で実行サイトを指定できます。
DRIVING_SITEヒントを使用したSELECT文の例を次に示します。コピーSELECT /*+DRIVING_SITE(dept)*/ * FROM emp, dept@remote.com WHERE emp.deptno = dept.deptno;
💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?
Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?




コメント