DB2のオプティマイザ
いまだ不慣れなDB2で以下のような問い合わせを実行した。
SELECT * FROM t
WHERE c1 LIKE 'xxx%'
ORDER BY c2;
これがとても遅いのである。c1、c2にはそれぞれ別の索引が設定されているのだが、どうもc2の索引に対してFULL SCANが実行されているっぽい。
SELECT * FROM t
WHERE c1 LIKE 'xxx%';
のようにORDER BYを外すと、期待通りc1の索引でRANGE SCANされる。しかしながらソートがかからないのも、実行速度が遅いのも具合が悪い。
Oracleなら
SELECT /*+ INDEX(t index_c1) */ * FROM t
WHERE c1 LIKE 'xxx%'
ORDER BY c2;
のようにオプティマイザにヒントを与えれば使いたい索引が使われるようになるが、DB2ではそうした手段が見当たらない。仕方がないので
SELECT * FROM t
WHERE c1 LIKE 'xxx%'
ORDER BY c2 || ' ';
ORDER BY句の項目をソート順に影響のない式にしてc2の索引が使われないようにした。
こういう書き方ってDB2ではよくあることなんだろうか。それともまともな対応方法があるのだろうか。