表の結合を極めるチューニング・テクニック:Oracle SQLチューニング講座(10)(1/4 ページ)
本連載では、Oracleデータベースのパフォーマンス・チューニングの中から、特にSQLのチューニングに注目して、実践レベルの手法を解説する。読者はOracleデータベースのアーキテクチャを理解し、運用管理の実務経験を積んでいることが望ましい。対象とするバージョンは現状で広く使われているOracle9iの機能を基本とするが、Oracle 10gで有効な情報も随時紹介していく。(編集局)
前回までは、索引に関するチューニング・テクニックを説明しました。今回からは表の結合に関するパフォーマンス向上方法を考えてみます。結合処理は、正規化されたデータベースでは、必ず必要になる処理であり、パフォーマンスが問題となりやすい部分でもあります。ここでは、参照する表の件数、絞り込み条件の有無などを変更し、結合の種類によって処理時間、アクセスブロック数などがどのように変わるか、実例を挙げて説明していきます。結合の種類については第3回「SQLチューニングの必須知識を総ざらい(後編)」を参照してください。
大きな表の大部分のデータを結合する場合
まず、集計処理などに代表される、表の大部分のレコードを取得するような結合処理を例に、結合方法によってどのような違いが出るのかを見ていきたいと思います。
以下の例ではデータ件数が約600万件の「LINEITEM」表と1万件の「SUPPLIER」表を結合して、約600万件全レコードを取得する検索を実行しています。ディメンション表(親表)に当たる「SUPPLIER」表の「s_suppkey」列に「PK_SUPPLIER」主キー索引が、「LINEITEM」表の「l_suppkey」列に「FK_SUPPKEY」索引が作成されています。
結合処理が「ネステッド・ループ結合」「ソート/マージ結合」「ハッシュ結合」となるように、SQLに「USE_NL」「USE_MERGE」「USE_HASH」の各ヒントを指定し、実行計画、実行統計を確認していきます。実行統計の見方に関しては、第5回「SQLチューニングの基盤となる統計情報 Page 3」を参照してください。
ネステッド・ループ結合
図1では、「USE_NL」ヒントと「ORDERED」ヒントを使用し、FROM句に指定した順番で、ネステッド・ループ結合が行われるようにオプティマイザに指示しています。
実行計画を確認すると、「LINEITEM」表が外部表(駆動表)として全表スキャンされ、1レコードずつ取り出すごとに「PK_SUPPLIER」索引を使用して「SUPPLIER」表とネステッド・ループ結合されていることが分かります。
では、外部表を「SUPPLIER」表に変更した場合にはどうなるでしょうか? トレース出力結果を見てみましょう。
FROM句の順番を変更したことで「SUPPLIER」表が外部表として選択され、全表スキャンによって1レコードずつ取り出し、「FK_SUPPKEY」索引を使用して内部表の「LINEITEM」表と結合するネステッド・ループ結合が行われています。外部表に件数の少ない「SUPPLIER」表を選択しているにもかかわらず、処理時間は4万2431秒(約11時間50分)と大幅に長くなってしまっています。
図1のケースとの処理時間の差は、600万件という大量のデータを、全表スキャンによるマルチブロック読み込みで取得してくる場合と、索引スキャンによるシングル・ブロック読み込みで取得してくる場合の効率の差により引き起こされています。
Copyright © ITmedia, Inc. All Rights Reserved.