最近我将Postgresql从9.1版升级到9.2版。新的计划程序使用错误的索引和查询执行时间太长。
查询:
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)
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版本,其中planner在searching_id上使用索引。在9.2版本中,规划器不会使用该索引并按search_id过滤行。
当我在没有ORDER BY id的9.2版本查询上执行时,planner在searching_id上使用索引,但我需要按id排序。
我还尝试在子查询中选择行并在第二个查询中对其进行排序,但解释显示,规划器在正常查询中执行相同操作。
select * from (
SELECT mentions.* FROM mentions WHERE (searches_id = 7646553))
AS q1
order by id asc
你会推荐什么?
答案 0 :(得分:1)
如果searching_id#7646553行超过表的百分之几,那么该列上的索引将不会被使用,因为表扫描会更快。做一个
select count(*) from mentions where searches_id = 7646553
并与总行数进行比较。
如果它们不到表的百分之几,那么试试
with m as (
SELECT *
FROM mentions
WHERE searches_id = 7646553
)
select *
from m
order by id asc
或创建综合索引:
create index index_name on mentions (searches_id, id)
如果searching_id的值较低cardinality,则按相反的顺序创建相同的索引
create index index_name on mentions (id, searches_id)
待办事项
analyze mentions
创建索引后。
答案 1 :(得分:0)
对我来说,我有索引,但它们都基于3列,我没有调出索引中的一列,所以它正在对整个事情进行seq扫描。可能的修复:更多的索引,但使用更少的列(和/或切换列顺序)。
我们看到的另一个问题是我们有正确的索引,但显然它是"无效" (创建不好的CONCURRENT?)索引。所以放弃它并创建它(或重新索引它)并开始使用它。
另见http://www.postgresql.org/docs/8.4/static/indexes-multicolumn.html