Senna (Tritonn) とは、未来検索ブラジルが開発した全文検索エンジンで、2indという機能があります。
(http://d.hatena.ne.jp/keyword/Senna)
2ind(2インデックス同時使用)というのは
MySQLなどでクエリを実行する際、1つのテーブルに対して、全文検索用のFULLTEXTインデックスと、他のインデックスを組み合わせて利用(インデックスマージ)できる機能です。
http://qwik.jp/tritonn/userguide.html#0cb0baa8b27d86e9233f601a9cc9cc4f
この機能を使わず全文検索を実行した場合、関連度合いでソートされた結果が返されます。ですが、大体の用途において、更新日時などでソートしたいことが多いと思います。
例えば、このようなテーブル構造
Field | Type | Null | Key | Default | Extra |
---|---|---|---|---|---|
id | int(10) unsigned | NO | PRI | 0 | |
title | varchar(100) | NO | FULLTEXT | ||
time | int(10) unsigned | NO | MUL | 0 |
- id => データID(インデックス:Primary)
- title => 本文(インデックス:FULLTEXT)
- time => データが更新されたUNIXタイム(インデックス:INDEX)
このテーブルにおいて、titleの全文検索をtime順に並べてidを取得するクエリは
SELECT `id` FROM `tbl_name` FORCE INDEX ( `time` ) WHERE MATCH ( `title` ) AGAINST ( '検索したいテキスト' ) ORDER BY `time` LIMIT 0 , 10
となります。
シンプルなクエリで特に問題ないように見えますが、LIMIT句が効かなくなるバグがあります。
この問題が確認された環境ですが、
Tritonn 1.0.12(MySQL5.0.87、linux-x86_64)
現在の最終バージョンです。
解決するには
さて解決する方法は、重複を省略するDISTINCT句を加えるだけです。
SELECT DISTINCT `id` FROM `tbl_name` FORCE INDEX ( `time` ) WHERE MATCH ( `title` ) AGAINST ( '検索したいテキスト' ) ORDER BY `time` LIMIT 0 , 10
これだけで、LIMIT句がきちんと動くようになります。
MySQLでDISTINCT句を使うと「インデックスが使われなくなるんじゃないの?」という懸念はあるのですが、EXPLAINで確認したところ「Using Where」が返ってきていたので、大丈夫みたいです。
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | tbl_name | index | NULL | time | 3 | NULL | 128481 | Using where |
※この記事は引っ越し元のブログから保存用にもってきたものです。この頃(2015年)はsennaはあまり使っていないのですが、覚書として。
0 件のコメント :
コメントを投稿