【发布时间】:2016-03-22 08:07:26
【问题描述】:
我有一个在 postgres 表上选择的有趣案例:
advert (~2.5 million records)
id serial,
user_id integer (foreign key),
...
这是我的选择:
select count(*) from advert where user_id in USER_IDS_ARRAY
如果USER_IDS_ARRAY length
Aggregate (cost=18063.36..18063.37 rows=1 width=0) (actual time=0.362..0.362 rows=1 loops=1)
-> Index Only Scan using ix__advert__user_id on advert (cost=0.55..18048.53 rows=5932 width=0) (actual time=0.030..0.351 rows=213 loops=1)
Index Cond: (user_id = ANY ('{(...)}'))
Heap Fetches: 213
Planning time: 0.457 ms
Execution time: 0.392 ms
但是当USER_IDS_ARRAY长度> 100时:
Aggregate (cost=424012.09..424012.10 rows=1 width=0) (actual time=867.438..867.438 rows=1 loops=1)
-> Seq Scan on advert (cost=0.00..423997.11 rows=5992 width=0) (actual time=0.375..867.345 rows=213 loops=1)
Filter: (user_id = ANY ('{(...)}'))
Rows Removed by Filter: 2201318
Planning time: 0.261 ms
Execution time: 867.462 ms
无论 USER_IDS_ARRAY 中的 user_id 是什么,只有长度很重要。
有人知道如何针对超过 100 个 user_id 优化此选择吗?
【问题讨论】:
-
您是否尝试过仅从
advert中选择而没有加入?过滤超过 100 个用户 ID 并查看它是否使用索引。 -
@Sevanteri 是的,你是对的,与广告选择相同的情况。只用一张表简化了我的问题。
-
对。似乎查询计划者只是认为最好进行 seq 扫描。您可以为表格运行
analyze,看看是否有帮助。 -
@Sevanteri 对广告的分析没有帮助
-
显示
ix__advert__user_id的定义。
标签: postgresql explain