最近我将Postgresql从9.1升级到9.2版本。新计划程序使用错误的索引并且查询执行时间过长。Postgresql计划器使用错误索引
查询:
explain SELECT mentions.* FROM mentions WHERE (searches_id = 7646553) ORDER BY id ASC LIMIT 1000
解释9.1版本:
Limit (cost=5762.99..5765.49 rows=1000 width=184)
-> Sort (cost=5762.99..5842.38 rows=31755 width=184)
Sort Key: id
-> Index Scan using mentions_searches_id_idx on mentions (cost=0.00..4021.90 rows=31755 width=184)
Index Cond: (searches_id = 7646553)
Expain在9.2版本:
Limit (cost=0.00..450245.54 rows=1000 width=244)
-> Index Scan using mentions_pk on mentions (cost=0.00..110469543.02 rows=245354 width=244
Index Cond: (id > 0)"
Filter: (searches_id = 7646553)
正确的做法是在9.1版本中,在那里策划者采用指数searches_id。在9.2版本规划器中,不会使用该索引并通过sear_id过滤行。
当我在没有ORDER BY id的情况下执行9.2版本查询时,planner使用了searchable_id上的索引,但我需要按ID排序。
我也尝试在子查询中选择行并在第二个查询中对其进行排序,但是解释显示,规划器与正常查询中的行为相同。
select * from (
SELECT mentions.* FROM mentions WHERE (searches_id = 7646553))
AS q1
order by id asc
你会推荐什么?
@Pajak你尝试我建议CTE? '用......' – 2013-03-01 13:15:55
Thx寻求帮助。但是问题不在search_id#7646553。只有65行,表中提到的总行数为150毫升。 当我解释查询选择计数(*)从提及where searching_id = 7646553,它使用正确的索引sear_id。 我不想创建新的索引,因为我认为这些searches_id是要执行的正确索引。 – 2013-03-01 13:16:36
现在我发现最好的解决方案是执行 set enable_indexscan = false;在运行查询之前运行 ,查询后切换为true。它的工作原理,但它不是优雅的解决方案。 – 2013-03-01 13:16:58