某DBにて、いろいろ試行錯誤しながら、日本語による全文検索を実装することができた。
はたして本当に効果があったのだろうか・・・と調べてみる。
全レコード数:32740
フィールド(フィールドタイプ:TEXT)には、日本語による文章を入れてあり、
全体のうち、4つのレコードのに
世界最大のカルデラを持った阿蘇5岳の一つ、山頂のギザギザが特徴的な根子岳です。(省略)という文章が入っている。で、全レコードから「ギザギザ」という文字で検索するとする。この4レコードを探すとする。
LIKEでやる場合、
FROM `main`
WHERE COMMENT LIKE "%ギザギザ%"
レコード表示 0 - 3 (4 合計, Query took 3.1908 sec)
と、3秒ちょっとかかった。(実はサーバ自体の性能もあまりよくないんだけれど)
EXPLAINすると、rowsの値は、総レコード数と同値であった。つまり、すべてのレコードをなめていることになる。LIKE で、%ほげ%にしているから、インデックスは効かないのである。(ただし、インデックスが効かない場合でも、もっと速い時もある)
次に、MySQLの全文検索機能を使っての検索を行ってみる。
FROM `main`
WHERE MATCH (ftext) AGAINST ('a5aea5b6a5aea5b6')
レコード表示 0 - 3 (4 合計, Query took 0.0043 sec)
なななんと、0.00043秒!!!単純計算で約800倍速くなったことになる。EXPLAINの結果のrowsは、1である。インデックスが最高に効いてる状態。
・・・すばらしぃ〜(うっとり)
もちろん、検索のキーによっては、ここまでは差が出ない場合もある。
ちなみに、↑の'a5aea5b6a5aea5b6'というのは、「ギザギザ」を16進数で表記したもの。こうやらないとMySQLが検索してくれないため。当然、事前に対象となるフィールドのデータを16進数にしたものを格納している。
MATCH〜AGAINSTでやるもう一つのメリットは、複数キーのand/orが楽ということ。
MySQL リファレンスマニュアル :: 6.8 MySQL 全文検索の下の方のBOOLEAN MODE 参照。
しかし、稼働しているサーバでは、なぜか無視されて、絶対orになるなーと、おもったら、MySQL 4.xからの機能だった。(稼働中のは3.23.25だったかな?)
・・・・しょうがないので、MATCH〜AGAINST をandで繋いだ(ダサっ
まぁいいや。あとは、検索枠を、ajaxでごにょごにょ・・
関連エントリ:
mysqlで日本語全文検索に挑戦!
mysqlで日本語全文検索するには?