wordsというテーブル(テーブルサイズは6G程度)があってそこに6000万行はいっています。
wordsにwordというtext型(非ユニーク、2文字~10文字程度の文字列)のカラムがあるのですが、
SELECT * FROM words where word = 'まめ';
という結果が60件前後返ってくるクエリの実行に5秒前後かかります。
インデックスは
CREATE INDEX words_word_index ON words USING btree(word);
となっています。
中間一致検索などはしません。wordカラムの完全一致のみで考えています。
パーティショニングしてテーブルサイズをそれぞれ2G程度になるようにしてみたのですが、2-3秒改善しただけでした。
このクエリの速度を上げる方法、あるいはそれに至る取り掛かりを教えていただけますでしょうか。
Pentium4 3GHz搭載マシンで、インデックスが有効利用されていて、結果行数が60程度であれば、もっと早くなりそうですが…
【1】ANALYZEで情報収集していない(あるいは情報が古い)のではないでしょうか?
1)EXPLAIN を実施して結果をメモる
2)ANALYZE を実施
3)再び EXPLAIN を実施して先の結果と比較する
【2】更新系ではなく蓄積系であるならば(定期的に)データを物理的に並び替えてみては?
1)CLUSTER を実施
2)並び替えたので再び ANALYZE を実施
3)EXPLAIN を実施して先の結果と比較する
完全一致だけなら、ハッシュインデックスを使う手はあるかもしれません。
上記ページの真ん中ぐらいに、ハッシュインデックスに関して記述があります。
ただ、
パーティショニングしてテーブルサイズをそれぞれ2G程度になるようにしてみたのですが、2-3秒改善しただけでした。
パーティショニングで、5 秒程度の物が 2~3 秒に改善したのであれば、I/O の問題が一番、大きいのかもしれません。だとすれば、SSD にしてしまうのが、お金はかかるけど、簡単な改善方法かもしれません。
ソートしておけば 少しは 速くなるかも・・・。
六千万件で 6秒なら 許容範囲だよねぇって 言うしかない。
これが 1秒じゃないと 絶対ダメ!?って?
サーバースペックは
CPU:Intel(R) Pentium(R) 4 CPU 3.00GHz
メモリ:4G
です。
SSDを買えが答えなら、そうします…。