2009年6月にUsagi-Projectに寄稿したもの。
日記データが膨大になってきて日記検索のI/Oがサーバ全体の足を引っ張るようになってきたので、検索の高速化をしてみました。
方法はmysqlを日本語全文検索対応のTritonnプロジェクト版に変更し、それに合わせて検索部分を修正します。
手元の日記データ37万件400Mくらいのc_diaryテーブルをPentiumM1.6GHzのマシンで検索したところ(検索クエリは後述)検索速度が15倍以上になりました。
LIKE検索 平均5.3秒
Tritonn検索 平均0.3秒
以下手順。
1)Tritonnインストール(CentOS5サーバの場合)
まずは既存のDBを念のためバックアップ
[code]# mysqldump -u root -p mynets_db > dump.sql[/code]
mysqlを置き換えるためmysqlのインストールを確認
[code]# rpm -qa | grep -i mysql
mysql-5.0.45-7.el5[/code]
mysqlをremove
通常dovecotで利用されているので、dovecotを停止してから作業
[code]# service dovecot stop
# yum remove mysql[/code]
perl-DBIのインストールを確認
[code]# rpm -qa | grep -i perl-DBI
perl-DBI-1.52-1.fc6[/code]
最新のtritonn-1.0.12-mysql-5.0.67パッケージ群をダウンロード
[code]# mkdir download
# cd download/
# wget http://iij.dl.sourceforge.jp/tritonn/36448/MySQL-client-5.0.67-tritonn.1.0.12.i386.rpm
# wget http://iij.dl.sourceforge.jp/tritonn/36448/MySQL-devel-5.0.67-tritonn.1.0.12.i386.rpm
# wget http://iij.dl.sourceforge.jp/tritonn/36448/MySQL-server-5.0.67-tritonn.1.0.12.i386.rpm
# wget http://iij.dl.sourceforge.jp/tritonn/36448/MySQL-shared-5.0.67-tritonn.1.0.12.i386.rpm
# wget http://iij.dl.sourceforge.jp/tritonn/36448/mecab-0.97-tritonn.1.0.12.i386.rpm
# wget http://iij.dl.sourceforge.jp/tritonn/36448/mecab-ipadic-2.7.0.20070801-tritonn.1.0.12.i386.rpm
# wget http://iij.dl.sourceforge.jp/tritonn/36448/senna-1.1.4-tritonn.1.0.12.i386.rpm[/code]
以下の順番でインストール
[code]# rpm -ivh mecab-0.97-tritonn.1.0.12.i386.rpm
# rpm -ivh mecab-ipadic-2.7.0.20070801-tritonn.1.0.12.i386.rpm
# rpm -ivh senna-1.1.4-tritonn.1.0.12.i386.rpm
# rpm -ivh MySQL-shared-5.0.67-tritonn.1.0.12.i386.rpm
# rpm -ivh MySQL-client-5.0.67-tritonn.1.0.12.i386.rpm
# rpm -ivh MySQL-server-5.0.67-tritonn.1.0.12.i386.rpm
# rpm -ivh MySQL-devel-5.0.67-tritonn.1.0.12.i386.rpm[/code]
MySQLはインストール後すぐに起動するのでrootのパスを設定
[code]# /usr/bin/mysqladmin -u root password ‘rootpassword'[/code]
MySQLへのログイン確認
[code]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.0.67-modified MySQL Community Server (GPL) (portions (c) Tritonn Project)
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the buffer.
mysql>[/code]
これでTritonnのインストール完了
入れ替え前のDBもたぶん大丈夫なはずだが、もし使えない時には新規にDB作成して、バックアップデータをリストアする
[code]# mysql -u root -p
mysql> CREATE DATABASE mynets_db DEFAULT CHARACTER SET utf8;
mysql> quit
# mysql -u root -p mynets_db < dump.sql[/code]
2)Tritonn用のindex作成
[code]# mysql -u root -p
mysql> use mynets_db;
mysql> ALTER TABLE c_diary ADD FULLTEXT fullindex USING NGRAM,SECTIONALIZE (subject, body);[/code]
件数が多いと相当時間がかかるのでじっと待つ
完了したらテスト検索してみる(testで検索)
[code]mysql> SELECT * FROM c_diary WHERE (public_flag = ‘public’ or public_flag = ‘open’) AND MATCH (subject, body) AGAINST (“test”) ORDER BY r_datetime DESC;[/code]
LIKE検索と時間を比較してみる
[code]mysql> SELECT * FROM c_diary WHERE (public_flag = ‘public’ or public_flag = ‘open’) AND (subject LIKE ‘%test%’ or body LIKE ‘%test%’) ORDER BY r_datetime DESC;[/code]
3)MyNETSの検索部分の修正
webapp/lib/db/read/diary.phpの新規日記検索の項目を以下のように修正
$s[code]elect = ‘SELECT *’;
$from = ‘ FROM ‘ . MYNETS_PREFIX_NAME . ‘c_diary’;
$where = ” WHERE (public_flag = ‘public’ or public_flag = ‘open’)”;
if ($keyword) {
//全角空白を半角に統一
$keyword = str_replace(‘ ’, ‘ ‘, $keyword);
//SQL Injection対策
$keyword = str_replace(‘\\’, ”, $keyword);
$keyword = str_replace(‘”‘, ”, $keyword);
$keyword = str_replace(‘;’, ”, $keyword);
$keyword = str_replace(‘)’, ”, $keyword);
$keyword = check_search_word($keyword);
$where .= ‘ AND MATCH (subject, body) AGAINST (“‘ .$keyword. ‘” IN BOOLEAN MODE)’;
}
$order = ” ORDER BY r_datetime DESC”;[/code]