Mroonga 3.11に追加されるDATETIME型のORDER BY最適化
mysql groonga

Mroonga 3.11に追加されるDATETIME型のORDER BY最適化

このエントリーをはてなブックマークに追加

こんにちは、DBAのたなかです。

このエントリーは 全文検索エンジンGroonga Advent Calendar 2013 の10日目です。

弊社の某サービスでは全文検索にMroongaを使って不思議なトラフィックパターンをさばいていますが、Mroonga 3.11(2013/12/29リリース *予定*)で加えられる新しい最適化についての紹介です。

エンドユーザー向けの全文検索だと、

mysql> SELECT .. FROM .. WHERE MATCH(fulltext_col) AGAINST '..' AND datetime_col> '2013-12-01' ORDER BY datetime_col DESC LIMIT 100, 20;

なんてことをやりたくならないでしょうか? 「xxというキーワードを含むページのうち、今月更新されたものを更新日の新しいものから」というケースです。検索結果が複数に分かれていて、LIMIT .. OFFSET ..で取るイメージです。

これがまあ遅かったんです。

( ゚д゚) えっウチのMroongaフツーに速いよ何言っちゃってんの。

はい。弊社の環境でも、*検索ワードによって* はそれなりのレスポンスタイムで返ってきていたんですが、*検索ワードによって* はかなりレスポンスタイムが悪かったのです。MATCH .. AGAINST ..だけで100万行HITしちゃうようなケース、いわゆるビッグワードの検索です。

mysql> show profile;
+-------------------------+----------+
| Status                  | Duration |
+-------------------------+----------+
| starting                | 0.000063 |
| checking permissions    | 0.000007 |
| Opening tables          | 0.000012 |
| System lock             | 0.000007 |
| init                    | 0.000021 |
| optimizing              | 0.000009 |
| statistics              | 0.000403 |
| preparing               | 0.000015 |
| FULLTEXT initialization | 0.857213 |
| executing               | 0.000016 |
| Sorting result          | 3.174404 |
| Sending data            | 0.001261 |
| end                     | 0.000015 |
| query end               | 0.000005 |
| closing tables          | 0.002170 |
| freeing items           | 0.002900 |
| logging slow query      | 0.000007 |
| logging slow query      | 0.000034 |
| cleaning up             | 0.000005 |
+-------------------------+----------+
19 rows in set, 1 warning (0.00 sec)

遅い。。ヤバイくらい遅い。。Sorting resultに3秒ですって。

( ゚д゚) 奥様それsort_buffer_sizeがイケてないんじゃありませんこと? 人生が曲がっていてよ?

sort_buffer_sizeを増やしてみたり、tmpdirを/dev/shmに変えてみたり、ソートに効きそうなことは一通りやったんですが誤差程度しか改善せず。

ストレージモードでのORDER BY .. LIMIT最適化 が効くかなぁと思ったんですが、これは当時(夏の日差しが暑い日だった気がします) INT型のカラムの等価検索(3.07からはVARCHAR型も追加)でしかサポートされておらず、DATETIME型では無理。

が、メーリングリストに

INT型の"<"演算子もサポートしたよ!

という男前なメールが流れているのを見て、

( ´∀`) 俺のためにDATETIME型もサポートしる

と振ってみたところ、

 1 日 で 対 応 し て く れ ま し た …((((;゚д゚))))

それが2013/12/06の出来事だったので、この修正は2013/12/29のMroonga 3.11(なんか不吉な響き)に取り込まれてリリースされる予定ですが、あまりにも垂涎モノの機能追加のため、最新版(nightly release)で突っ込むことにしました。コンパイルオプションが-O0 -g3になってるので、飽くまでデバッグ用なんですかね? 問答無用で-O3でmakeしましたが。

さて、どうなるかな…?

mysql> show profile;
+-------------------------+----------+
| Status                  | Duration |
+-------------------------+----------+
| starting                | 0.000111 |
| checking permissions    | 0.000007 |
| Opening tables          | 0.000018 |
| init                    | 0.000029 |
| System lock             | 0.000010 |
| optimizing              | 0.000012 |
| statistics              | 0.048629 |
| preparing               | 0.000035 |
| FULLTEXT initialization | 0.574461 |
| Sorting result          | 0.000017 |
| executing               | 0.000003 |
| Sending data            | 0.000010 |
| Creating sort index     | 0.005282 |
| end                     | 0.000007 |
| query end               | 0.000004 |
| closing tables          | 0.000393 |
| freeing items           | 0.002664 |
| cleaning up             | 0.000013 |
+-------------------------+----------+
18 rows in set, 1 warning (0.00 sec)

( ゚д゚)

(つд⊂)ゴシゴシ

(;゚д゚)

(つд⊂)ゴシゴシ
 _, ._
(;゚ Д゚)

おい1秒余裕で切りましたよ。圧倒的じゃないですか我が軍は。

( ー`дー´) ここに厚く御礼申し上げます(キリ


名無しのエンジニア
レガシーコードとAspectMock
Elasticsearchとkuromojiでちゃんとした日本語全文検索をやるメモ