Kouhei Sutou
kou****@clear*****
2013年 12月 6日 (金) 17:18:26 JST
須藤です。 In <JxzEf****@netag*****> "[groonga-dev,01944] Re: FULLTEXTインデックス以外での絞り込みについて" on Fri, 06 Dec 2013 11:13:11 +0900, sinoh****@netag***** wrote: > 本件と直接関係ないのですが、 > > 全文検索は、爆速なのですが、通常のインデックス性能が、それに比べ遅いので > 1. ちょっとテストしたら速かった。 > 2. アプリ作成してたら、なんか遅い。思ったのと違うー > 3. テーブル設計から見直し。 > な経験をされる方ってけっこういらっしゃるのではないでしょうか? うおー! そ、そうなんでしょうか。。。 > みなさん > - そもそも普通のインデックスの速度ってこれが限界? これって、 >> mysql> SELECT COUNT(*) FROM xxx WHERE birth_year > 1973; >> +----------+ >> | COUNT(*) | >> +----------+ >> | 4996106 | >> +----------+ >> 1 row in set (1.24 sec) みたいなケースが遅いってことですよね? 試しに、同じデータをInnoDB(パラメーターはデフォルト)に入れ て測ってみました。 mysql> CREATE TABLE yyy ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, name TEXT, birth_year SMALLINT UNSIGNED, PRIMARY KEY (id), KEY birth_year (birth_year) ) ENGINE=InnoDB DEFAULT CHARSET=UTF8; Query OK, 0 rows affected (0.15 sec) mysql> insert into yyy select * from xxx; Query OK, 10000000 rows affected (4 min 45.02 sec) Records: 10000000 Duplicates: 0 Warnings: 0 mysql> SELECT COUNT(*) FROM yyy WHERE birth_year > 1973; +----------+ | COUNT(*) | +----------+ | 4996106 | +----------+ 1 row in set (0.89 sec) た、たしかにInnoDBの方が速いですねぇ。。。 Mroongaでそんなに遅くなりそうなことはしていないんですけどねぇ、 と思って直接Groongaで確認してみたら、直接Groongaの方が遅かっ たです。。。 mysql> select mroonga_command("select xxx --filter 'birth_year > 1973' --limit 0")\G *************************** 1. row *************************** mroonga_command("select xxx --filter 'birth_year > 1973' --limit 0"): [[[4996106],[["_id","UInt32"],["_key","UInt32"],["birth_year","UInt16"],["id","UInt32"],["name","LongText"]]]] 1 row in set (1.47 sec) Groongaのどこらへんが遅いのかちょっと測ってみたのですが、 結果レコードセットを作るところが遅いですねぇ。。。 結果レコードセットを作るの以外(検索を含む)で0.1秒くらいなの で、結果レコードセットを作るので1秒以上かかっていますねぇ。 http://groonga.org/ja/publication/presentation/groonga-night-2-the-future.pdf の18ページのベンチマークを見ると、grn_hash(結果レコードセッ トを入れるテーブル)は1レコードあたり0.5マイクロ秒かかるっぽ くて、今回は500万件ヒットしているので、 0.5 * 5_000_000 = 2500000.0マイクロ秒 = 2.5秒 となって、まぁ、1秒以上かかりそうだなぁという感じはしますね。 結果レコードセットが遅いということはわかったので、そんなに大 量にヒットしないやつなら速いはずです。 ということで、試してみました。 Mroonga: mysql> SELECT COUNT(*) FROM xxx WHERE birth_year > 2000; +----------+ | COUNT(*) | +----------+ | 1624200 | +----------+ 1 row in set (0.21 sec) InnoDB: mysql> SELECT COUNT(*) FROM yyy WHERE birth_year > 2000; +----------+ | COUNT(*) | +----------+ | 1624200 | +----------+ 1 row in set (0.32 sec) うん、150万件くらいならMroongaの方がInnoDBより速いですね。 と、調べてみたんですが、 > - そもそも普通のインデックスの速度ってこれが限界? って↑で調べてみたケースであっていますか?もし違っていたら、 再現できるデータを教えてもらえるとこちらでも確認できて助かり ます! -- 須藤 功平 <kou****@clear*****> 株式会社クリアコード <http://www.clear-code.com/> (03-6231-7270) Groongaサポート: http://groonga.org/ja/support/ パッチ採用はじめました: http://www.clear-code.com/recruitment/ コミットへのコメントサービスはじめました: http://www.clear-code.com/services/commit-comment.html