【问题标题】:Understanding slow Bitmap Heap Scan in LIKE query了解 LIKE 查询中的慢位图堆扫描
【发布时间】:2017-06-23 21:11:08
【问题描述】:

以下查询在 Postgres 上运行

SELECT COUNT(*)
FROM "posts"
WHERE "posts"."author_id" = 20
AND ("posts"."title" ILIKE '123');

显然涉及一个非常慢的位图堆扫描。我怎样才能诊断出速度如此之慢的原因?我该怎么做才能让它表现得更好?

my-app::DATABASE=> EXPLAIN ANALYZE VERBOSE
my-app::DATABASE-> SELECT COUNT(*)
my-app::DATABASE-> FROM "posts"
my-app::DATABASE-> WHERE "posts"."author_id" = 20
my-app::DATABASE-> AND ("posts"."title" ILIKE '123');
                                                                            QUERY PLAN                                                                            
------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=25516.64..25516.64 rows=1 width=0) (actual time=35632.267..35632.267 rows=1 loops=1)
   Output: count(*)
   ->  Bitmap Heap Scan on public.posts  (cost=307.46..25516.64 rows=1 width=0) (actual time=35632.264..35632.264 rows=0 loops=1)
         Recheck Cond: (posts.author_id = 20)
         Filter: ((posts.title)::text ~~* '123'::text)
         Rows Removed by Filter: 22216
         Heap Blocks: exact=15419
         ->  Bitmap Index Scan on index_posts_on_author_id_and_state  (cost=0.00..307.46 rows=23586 width=0) (actual time=54.585..54.585 rows=22235 loops=1)
               Index Cond: (posts.author_id = 20)
 Planning time: 0.853 ms
 Execution time: 35632.405 ms
(11 rows)

【问题讨论】:

  • 没有通配符的情况下为什么要使用ILIKE
  • 这只是探索查询策略,但一般它可能会通过后缀或前缀进行搜索。
  • 如果标题不是很大,则在 (author_id, title) 上创建索引
  • 谢谢,我试试看。

标签: sql postgresql


【解决方案1】:

查询的写法,没有索引可以做得更好。

但是你可以这样重写它:

SELECT count(*)
FROM posts
WHERE posts.author_id = 20
AND lower(posts.title) LIKE lower('abc%');

那么下面的索引可以帮助在某些情况下

CREATE INDEX posts_auth_title_ind
   ON posts (
      author_id,
      lower(title) text_pattern_ops
   );

LIKE 需要text_pattern_ops,除非您使用的是CPOSIX 排序规则。

如果搜索模式以通配符开头,则没有 B 树索引可以提供帮助。在这种情况下,您可以尝试pg_tgrm 索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 2011-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-24
    • 1970-01-01
    相关资源
    最近更新 更多