【发布时间】: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