ただでさえ複雑なプログラムに、度重なる仕様変更……設計当初の予定より、ずっと多くの情報をデータベースから抜き出さなくてはならなくなる、というのはSE業界にはよくあることですよね。
しかし、だからと言って処理速度が犠牲にするわけにはいきません。実用化させるためには、高度なパフォーマンスチューニングが必要になってきます。
今回はそんな事態に対処するための、実用的なテクニックについてご紹介しましょう。
ヒント句を採用しよう
SQLのパフォーマンスチューニングにおいて、ヒント句は重要な要素の一つです。
作り手側がOracleに明示的に実行計画の作り方を指示することができるので、状況次第では絶大な効果をもたらすことができます。
ヒント句は簡単な構文なので是非おすすめしたいところですが、初心者にとってはなかなか理解しにくい物かも知れません。その効果を実感するには、「複雑すぎてOracleが実行計画を作れないSQL」に直面する必要があるのが難点です。
そんな初心者の方の助けになれるように、特に理解しやすく、効果の高い構文を二つご紹介しましょう。
・INDEX
Oracleに使用するインデックスを明示的に指定するヒント句です。データの検索を効率的に行うことができるので、パフォーマンスが飛躍的に上がります。
※使用例:
SELECT /*+ INDEX(T IDX_MCL_02) */ T.* FROM MCLT001 T WHERE KEY=:KEY;
→「IDX_MCL_02」というインデックスが使用される。
・LEADING
テーブルの結合順序を指示するためのヒント句です。件数の少ないテーブルから順に結合させ、検索対象のデータを限定することで、パフォーマンスを向上させます。
※使用例:
SELECT /* LEADING(B A C) */ A.* FROM MCLT001 A, MCLT002 B, MCLT003 C WHERE A.KEY = B.KEY AND B. KEY = C.KEY ;
→ 「B→A→C」の順序でテーブル結合が行われる。
ファンクション項目を用意しよう
プログラムの中には、どうしても結合条件の中でファンクションを使わなければならないことがあります。
しかしそれをするとインデックスが使用できなくなり、パフォーマンスの悪化に繋がってしまいます。
ファンクションでの結合を助ける「ファンクションキー」という機能もありますが、やはりSQLの発行のたびにファンクションの処理が走るので、速度低下は否めません。
おすすめの方法は、「ファンクションの結果を予めテーブルに格納しておく」というものです。レコードの登録直後から結果が変わらないことが前提ですが、いちいちファンクションが実行されないため、効率的にSQLを実行することができます。
日付は「適用日」ではなく「適用範囲」で設計しよう
これはパフォーマンスが劣化した後ではなく、設計段階で気を付けるべき点です。
データベースの定義の中で、よく見かける項目の一つに「適用日」というものがありますよね。
「○○○○年××月△△日からは?%で計算する」という仕組みで使われるもので、消費税などを想像してもらえれば、分かりやすいのではないでしょうか。
これはDB設計上美しく見えるかも知れませんが、SQLパフォーマンス的には良くありません。
このデータを抽出するためには、「YYYY年MM月DD日以前の最新のデータ」という指定をする必要があるからです。MAX関数を使ってサブクエリを作ってしまっては、当然遅くなってしまいますよね。
この問題は、適用日をFROM-TOで持たせたDB設計にすることで解決できます。
そうすることによって、MAX関数を使わず、かつインデックスも使用できる、優れた作りになるのです。
パフォーマンスチューニングは奥が深い
今回ご紹介した方法は、なるべく他ではあまり見かけないテクニックを意識してみました。
SQLを早くする技術は、これ以外にもたくさんあります。Oracleのインストール時の設定でも早くできたりもするので、興味のある方は色々調べてみてくださいね。