- 2006年8月26日 16:06
- MySQL
うちのサーバーに組み込み型の全文検索エンジンである「Senna」をインストールした。
データベースサーバーとしてMySQLを入れているんが、データ数が多くなってくると、あいまい検索がアホみたいに遅い。
何が最速のDBエンジンですか?と言いたくなるほど遅い。
たとえば、14万件のデータで、LIKE '%検索語句%'で検索すると、1分オーバー。
この状況で、検索エンジンを作ったところで誰がこんなサービス使うかっていう話で。
MySQLの仕様として、char型、varchar型、text型にもインデックスをつける事ができるが、検索語句の頭に「%」を付加した場合、インデックスは利用されないとの事。
という事は、検索ごとに14万件を頭から総ナメしているわけだ。
ただこれは、私が「フルテキストインデックス(全文検索)」って言葉を知らなかっただけで、通常、検索エンジンなんかはこの「フルテキストインデックス(全文検索)」というものを使うらしい。
この機能を使うとデータを単語ごとに区切った状態でインデックスを作成する為、検索速度も通常のインデックス検索並になる。
MySQLも、3.23より「フルテキストインデックス」をサポートしている。が、いまだに(現時点で、5.0.24)日本語は対応していないとの事。
英語の文章は最初から単語で区切られている為、インデックスも正常に作成されるが、日本語は単語の区切りにスペースなどを入れない為、インデックスが正常に作成されない。
となると、検索しても、目的のデータがひっかからないという事だ。
じゃあ、どうするか。日本語の単語データベースを作り、データを格納する際に単語で区切るか。。
んー。。無理。
必死でGoogleさんに問い合わせをかけたところ「Senna」という組み込み型の全文検索エンジンのサイトにたどり着いた。
この「Senna」は名前のとおり、日本語の全文検索を可能にするようだ。また、MySQLに組み込む事ができるとの事。
ただし、既にMySQLを導入済の場合は、ソースから再コンパイルする必要がある。。
MySQLのコンパイル時にはいつも手こずっているんで、辛い。。が、それをする以外ない。
以下「Senna」の導入手順。
Mecabのインストール
まず、形態素解析エンジンである「Mecab」をインストールする。
形態素解析エンジンというのは、日本語の単語データベースのようなもの。
以下のサイトより「Mecab」をダウンロード。
http://mecab.sourceforge.jp/#download
そして、ソースコンパイル。
$ tar zxfv mecab-0.93.tar.gz
$ cd mecab-0.93
$ ./configure
$ make
$ make check
# make instal
IPA辞書のインストール
次に、Mecab用の辞書をインストーする。
以下のサイトより「IPA辞書」をダウンロード。
http://mecab.sourceforge.jp/#download
そして、ソースコンパイル。
$ tar zxfv mecab-ipadic-2.7.0-20060707.tar.gz
$ cd mecab-ipadic-2.7.0-20060707
$ ./configure
$ make
# make instal
Sennaのインストール
そしていよいよ「Senna」のインストール。
以下のサイトより「Senna」をダウンロード。
http://qwik.jp/senna/Download.html
そして、ソースコンパイル。ふー。
$ tar xvfz senna-0.8.0.tar.gz
$ mv senna-0.8.0 senna
$ cd senna
$ ./configure --prefix=/usr
$ make
$ make instal
そして、半日ぐらいハマる。
makeを行った場合、ほぼ固まってしまうようだ。
コンパイルが完了しない場合は、以下のオプションでconfigureすると解決した。
$ ./configure --prefix=/usr --disable-nfkc
MySQLインストール
そして「MySQL」のインストール。
通常のインストールとは違い、「Senna」をバインディングさせる為、パッチを当て、configureオプションに「--with-senna」を付加してからコンパイルする。
初めてのインストールの場合は、新規ユーザとグループを作成。
セキュリティ上、専用のユーザを使用した方がよいとの事。
# groupadd mysql
# useradd -g mysql mysql
# passwd mysq
MySQLインストール用のソースコードmysql-5.0.24.tar.gzを入手。
http://www.mysql.com/downloads/
現時点で、本家サイトでは、5.0.24のソースコードがダウンロードできないようだ。
というわけで、以下のサイトよりGET。
http://fresh.t-systems-sfr.com/linux/src/mysql-5.0.24.tar.gz/
ここで、「5.022でいいじゃん。」と5.0.22で行こうとすると、私のようにまたハマるので注意。
以前は、sennaのソースに5.0.22にあうパッチが梱包されていたようだが、今、配布されているソースには5.0.24用のパッチだけが梱包されており、それを当てても失敗した。
5.0.21用のパッチであれば成功するらしいが、散々探しても見つからなかった。
※ これはMySQL5.0に限った話であり、試していないが、MySQL4を入れるのであれば話は別だと思う。
解凍し、ディレクトリを移動。
$ tar zxvf mysql-5.0.22.tar.gz
$ cd mysql-5.0.2
MySQLにパッチを当てる。
$ patch -p1 < ../senna/bindings/mysql/mysql-5.0.24.senna.diff
$ patch -p1 < ../senna/bindings/mysql/mysql-5.0.24.senna.2ind.dif
MySQLのconfigureを作成する。
$ libtoolize -c -f
$ aclocal-1.9
$ autoheader
$ automake-1.9 -c -a -i
$ autoconf
$ touch sql/sql_yacc.y
そして、コンパイル条件を設定する。※ ここはご自分の環境に合わせて下さい。
$ CFLAGS="-O3 -mcpu=pentium4 -I/usr" \
CXX="gcc -O3" \
CXXFLAGS="-O3 -mtune=pentium4 -felide-constructors -fno-exceptions -fno-rtti -I/usr" \
LDFLAGS="-L/usr/local/lib" \
./configure \
--prefix=/usr/local/mysql \
--with-charset=ujis \
--with-extra-charset=all \
--with-mysql-user=mysql \
--with-senna \
--enable-thread-safe-client \
--with-big-tables \
--with-extra-charsets=complex \
--enable-assembler \
--with-named-curses-libs=/usr/lib/libncurses.so.5 \
--with-low-memory \
--without-innodb \
--without-readlin
※ 全て一行として実行
コンパイル処理後、インストールを行う。
$ make
$ su -
# make install
初期データベースを生成。
# ./scripts/mysql_install_db
バイナリのオーナーをrootに、データディレクトリの所有権をmysqlに変更。
# chown -R root /usr/local/mysql
# chown -R mysql /usr/local/mysql/var
# chgrp -R mysql /usr/local/mysq
MySQLを起動
# /usr/local/mysql/bin/mysqld_safe &
MySQLが正常動作していることを確認
# /usr/local/mysql/bin/mysqladmin -u root pin
※「mysqld is alive」と表示されれば成功
管理者パスワードを設定
# /usr/local/mysql/bin/mysql -u root
mysql> SET PASSWORD FOR root@localhost=PASSWORD('******1');
パスワードの付加されていないユーザをすべて削除。
mysql > USE mysql;
mysql > DELETE FROM user WHERE password='';
データベースアクセス用の新規ユーザを設定
mysql > GRANT all privileges ON sample.* TO test@localhost IDENTIFIED BY '******';
mysql > exit;
起動スクリプト
# cp support-files/mysql.server /etc/rc.d/init.d/mysql
# chmod 755 /etc/rc.d/init.d/msyq
自動起動
# cd /etc/rc.d/init.d/
# chkconfig --add mysql
# chkconfig --level 3 mysql o
グローバル設定ファイルの設定
# cp support-files/my-medium.cnf /etc/my.cnf
# vi /etc/my.cnf
とりあえず、文字化対策
[mysqld]
default-character-set=ujis
skip-character-set-client-handshake
最後に再起動!
# /etc/rc.d/init.d/mysql restar
と、ここまでが、Senna binding MySQL のインストール。
Fedora5 を利用している場合は、gccのバージョンによってハマる可能性が高いのでご注意!
調べたところgccの2.95.3でないとうまくコンパイルできないという情報に行き着いたが、gccのバージョンを最新にしてやるとうまくいった。
それでもうまくいかない場合は、gccを現行バージョンと別にインストールしてみるといいかも。
※現行バージョンを上書きしないように注意する事。
gcc2.95.3のインストール
$ tar zxvf gcc-2.95.3.tar.gz $ cd gcc-2.95.3
インストール先を指定
$ ./configure \ --prefix=/usr/local/gcc-2.95.3 \ --enable-shared $ make CFLAGS='-O2 -march=i686' LIBCFLAGS='-O2 -march=i686' LIBCXXFLAGS='-O2 -march=i686 -fno-implicit-templates' bootstrap
# make install
# ln -s /usr/local/gcc-2.95.3 /usr/local/gcc2
# export PATH=/usr/local/gcc2/bin:$PATH
バージョンチェック
# gcc -v
gcc version 2.95.3 20010315 (release
MySQLをコンパイルする前に以下のコマンドを実行してからコンパイルする。
# export LD_LIBRARY_PATH=/usr/local/lib
これで、MySQLで全文検索ができるようになった。
テーブルを作成し、テスト。
CREATE TABLE test (
id INTEGER AUTO_INCREMENT,
PRIMARY KEY (id),
text TEXT NOT NULL,
FULLTEXT INDEX (text)
);
適当にデータを突っ込み、以下の文を実行する。
SELECT * FROM test WHERE MATCH (text) AGAINST('検索語句');
ちなみに、私の環境では、14万件のデータよりの検索に1分以上かかっていたのが1秒以下で検索できるようになった。
すごい!!
- Newer: Google Analytics HTTPSなページで警告
- Older: PHPフレームワークの動向