プロシージャの中で複雑なデータの加工処理を行う場合、よく加工中のデータを一時表に放り込んでそれを突っつき回すという実装方法をとることがありますが、一時表に大量のレコードが放り込まれる可能性がある場合は、一時表へのアクセス時のパフォーマンスにも十分に気をつけなければなりません。
一時表はセッションやトランザクション内で一時的に使われるだけなので統計情報がありません。
そのため、コストベース・オプティマイザが利用できず、ルールベースでSQLの実行計画が決められるのですが、一時表に格納されるデータの内容、アクセス時の結合条件、検索条件によっては的はずれな実行計画となることも多々ありあります。
一時表上で少量のレコードしか扱わない場合には特に気になりませんが、大量のレコードを扱うような場合には特にその的外れぶりが際立ってきます。
的はずれな実行計画のまま処理を実行すると、最適な実行計画と比較して数倍~数十倍パフォーマンスが悪化するということがあるのです。
大量のレコードを扱う一時表にアクセスするSQLのチューニングのポイントは普通の表に対するそれと大して変わりはありません。
まずはインデックスの作成を検討してみることです。
意外と見落としがちですが一時表にも普通の表と同じようにインデックスが作成することができます。
一時表に格納されるデータとそれにアクセスする際の検索条件を考慮してインデックスを作成し、作成したインデックスを有効に利用できるようSQL文の検索条件を記述すればかなり劇的にパフォーマンスを改善することも可能です。
ただ、これで大体は満足なパフォーマンスが得られると思いますが、思った通りにインデックスを使ってくれないこともあります。
このような場合には、SQLにINDEXヒントを埋め込んでやります。
また、複数のテーブルを結合する場合は、インデックスを適切に使用していても結合順序が不適切でパフォーマンスが悪化することがあります。
このような場合にはORDEREDヒント句を埋め込んでやると改善することがあります。
その他オプティマイザ・ヒントを埋め込むことによってパフォーマンスが改善するケースはいろいろあるでしょうが、この辺は実際に走らせながら試行錯誤するということになるでしょう。
なお、セッションやトランザクションをまたいで一時データを使いたい場合は、普通の表に一時データを格納することもありますが、これもまた的はずれな実行計画となることが多い。
一時表と違って統計情報があればコストベース・オプティマイザが使われるのですが、この統計情報はあてにならないことがほとんどだからです。
よって、このような一時データを格納する表についてもパフォーマンスに気をつけなければなりません。