Kouhei Sutou
kou****@clear*****
2017年 11月 26日 (日) 14:37:40 JST
須藤です。 In <20170****@clear*****> "[groonga-dev,04481] Re: 【ご報告】インデックスを使って検索したいときにシーケンシャルスキャン" on Fri, 15 Sep 2017 16:22:15 +0900 (JST), Kouhei Sutou <kou****@clear*****> wrote: >>>このデータを提供してもらえれば、推定ヒット数をだすロジックを >>>改良できるかもしれないのでご検討ください。 >> >> お役に立てるなら、やぶさかではありません。ただし、提供データは >> ロジック改良目的のみに使用していただき、その他には使用しないと >> いう条件です。 > > はい、それで結構です。 > 直接私にメールでダウンロードURLを教えてください! だいぶ遅くなってしまったのですが、確認しました。 ロード直後だと期待通りにインデックスを使っていました。 前に[groonga-dev,04477]で見せてもらったように推測値の方の rowsが2595875とか大きくなっているということもありませんでし た。 --- explain ( analyze, buffers ) SELECT c_id, videoid, title, tags FROM robot WHERE ( lower(tags) &@ lower('iphone') OR lower(title) &@ lower('iphone') ) AND ( lower(tags) &@ lower('ipad') OR lower(title) &@ lower('ipad') ) AND vc > 100000 order by vc DESC; -- QUERY PLAN -- --------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Sort (cost=84.84..84.89 rows=21 width=279) (actual time=93.691..93.846 rows=1540 loops=1) -- Sort Key: vc DESC -- Sort Method: quicksort Memory: 1002kB -- Buffers: shared hit=18 read=1521 -- -> Bitmap Heap Scan on robot (cost=0.27..84.37 rows=21 width=279) (actual time=84.244..92.587 rows=1540 loops=1) -- Recheck Cond: (((lower(tags) &@ 'iphone'::text) OR (lower(title) &@ 'iphone'::text)) AND ((lower(tags) &@ 'ipad'::text) OR (lower(title) &@ 'ipad'::text))) -- Filter: (vc > 100000) -- Heap Blocks: exact=1536 -- Buffers: shared hit=15 read=1521 -- -> BitmapAnd (cost=0.27..0.27 rows=21 width=0) (actual time=83.848..83.848 rows=0 loops=1) -- -> BitmapOr (cost=0.01..0.01 rows=10383 width=0) (actual time=78.106..78.106 rows=0 loops=1) -- -> Bitmap Index Scan on robot2_lower_r_delimmit_tags_idx (cost=0.00..0.00 rows=5191 width=0) (actual time=69.869..69.869 rows=6236 loops=1) -- Index Cond: (lower(tags) &@ 'iphone'::text) -- -> Bitmap Index Scan on robot2_lower_r_mecab_title_idx (cost=0.00..0.00 rows=5191 width=0) (actual time=8.234..8.234 rows=13615 loops=1) -- Index Cond: (lower(title) &@ 'iphone'::text) -- -> BitmapOr (cost=0.01..0.01 rows=10383 width=0) (actual time=4.378..4.378 rows=0 loops=1) -- -> Bitmap Index Scan on robot2_lower_r_delimmit_tags_idx (cost=0.00..0.00 rows=5191 width=0) (actual time=1.323..1.323 rows=933 loops=1) -- Index Cond: (lower(tags) &@ 'ipad'::text) -- -> Bitmap Index Scan on robot2_lower_r_mecab_title_idx (cost=0.00..0.00 rows=5191 width=0) (actual time=3.053..3.053 rows=3429 loops=1) -- Index Cond: (lower(title) &@ 'ipad'::text) -- Planning time: 0.593 ms -- Execution time: 94.824 ms -- (22 rows) ---- 原因ですが、おそらく、レコードの削除・更新を繰り返した結果、 インデックス内に無効なレコードの情報が残っていて、それのせい で見積が大きく上ブレしているのではないかと思います。 (PostgreSQLはVACUUMされるまで削除済み・更新前のレコードが残っ ています。) 以下のようにして手動でVACUUMしたあとでも同様の結果になるか確 認してみてもらえますか? VACUUM robot; これでインデックスを使うようになるなら↑の予想原因は当たって いたといえます。 通常は、適切なタイミングで自動でVACUUMが動いているので手動で VACUUMする必要はありません。が、もしかしたら、なんらかの理由 でしばらく動いていなかったのかもしれません。 あるいは、↓のようにインデックスを再作成した直後でも同様の結 果になるか確認してみてもらえますか? RECREATE INDEX robot2_lower_r_delimmit_tags_idx; RECREATE INDEX robot2_lower_r_mecab_title_idx; インデックスを再作成した直後は無効なレコード(削除済み・更新 前のレコード)がないので、これでもインデックスを使うようにな るなら、やはり↑の予想原因は当たっていたと言えます。 -- 須藤 功平 <kou****@clear*****> 株式会社クリアコード <http://www.clear-code.com/> Groongaベースの全文検索システムを総合サポート: http://groonga.org/ja/support/ パッチ採用 - プログラミングが楽しい人向けの採用プロセス: http://www.clear-code.com/recruitment/ OSS開発支援サービス: http://www.clear-code.com/blog/2016/6/27.html