« 武装練金にオーケンネタ | メイン | 軽度のガノタ症候群による認識不全 »

mysqlで日本語全文検索の効果

某DBにて、いろいろ試行錯誤しながら、日本語による全文検索を実装することができた。

はたして本当に効果があったのだろうか・・・と調べてみる。

全レコード数:32740
フィールド(フィールドタイプ:TEXT)には、日本語による文章を入れてあり、
全体のうち、4つのレコードのに

世界最大のカルデラを持った阿蘇5岳の一つ、山頂のギザギザが特徴的な根子岳です。(省略)
という文章が入っている。で、全レコードから「ギザギザ」という文字で検索するとする。この4レコードを探すとする。

LIKEでやる場合、

SELECT *
FROM `main`
WHERE COMMENT LIKE "%ギザギザ%"
レコード表示 0 - 3 (4 合計, Query took 3.1908 sec)

と、3秒ちょっとかかった。(実はサーバ自体の性能もあまりよくないんだけれど)
EXPLAINすると、rowsの値は、総レコード数と同値であった。つまり、すべてのレコードをなめていることになる。LIKE で、%ほげ%にしているから、インデックスは効かないのである。(ただし、インデックスが効かない場合でも、もっと速い時もある)

次に、MySQLの全文検索機能を使っての検索を行ってみる。

SELECT *
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が楽ということ。

SELECT * FROM hoge WHERE MATCH(fuga) AGAINST('aaa bbb' IN BOOLEAN MODE )
で、aaaまたはbbbが含まれるもの(OR)、
SELECT * FROM hoge WHERE MATCH(fuga) AGAINST('+aaa +bbb' IN BOOLEAN MODE )
で、aaaとbbbが含まれるもの(AND)を、検索できる。
MySQL リファレンスマニュアル :: 6.8 MySQL 全文検索の下の方のBOOLEAN MODE 参照。

しかし、稼働しているサーバでは、なぜか無視されて、絶対orになるなーと、おもったら、MySQL 4.xからの機能だった。(稼働中のは3.23.25だったかな?)

・・・・しょうがないので、MATCH〜AGAINST をandで繋いだ(ダサっ

まぁいいや。あとは、検索枠を、ajaxでごにょごにょ・・

関連エントリ:
mysqlで日本語全文検索に挑戦!
mysqlで日本語全文検索するには?

トラックバック

このエントリーのトラックバックURL:
http://www.ironhearts.com/diary/mt-tb-ih.cgi/174

コメントを投稿

2008年10月

      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

最近のコメント

小優 on 日々の記録: DELL4600Cで
よしぞう on 日々の記録: 4600C 表記の対
よしぞう on 日々の記録: 4600C 表記の対
on MySQL後で調べるメモ: DB接続後 目的のS
on 日々の記録: 「無くなった留め具」
on JavaScriptでクロスドメイン: >しかし、こういう小
junp on iMovieで静止画を取り込むと荒い: すいません困ってます
う〜ん・・・ on 素朴な疑問: にょうをした、きたな
困ってました on ATOKとIME2005が勝手に切り替わる問題: 何故か勝手に切り替わ
go on 日々の記録: 4600C、同じ症状

アーカイブ