2013-03-01 74 views
2

最近我将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 

你会推荐什么?

回答

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) 

如果searches_id具有低cardinality然后创建相反的同一指标order

create index index_name on mentions (id, searches_id) 

analyze mentions 

创建索引后。

+0

@Pajak你尝试我建议CTE? '用......' – 2013-03-01 13:15:55

+0

Thx寻求帮助。但是问题不在search_id#7646553。只有65行,表中提到的总行数为150毫升。 当我解释查询选择计数(*)从提及where searching_id = 7646553,它使用正确的索引sear_id。 我不想创建新的索引,因为我认为这些searches_id是要执行的正确索引。 – 2013-03-01 13:16:36

+0

现在我发现最好的解决方案是执行 set enable_indexscan = false;在运行查询之前运行 ,查询后切换为true。它的工作原理,但它不是优雅的解决方案。 – 2013-03-01 13:16:58

0

对我来说,我有索引,但他们都是基于3列,我没有叫出索引中的一列,所以它是在整个事情上进行seq扫描。可能的修复:更多的索引,但使用更少的列(和/或切换列顺序)。

我们看到的另一个问题是我们有正确的索引,但显然它是一个“无效”(创建不佳的CONCURRENT?)索引。所以放下它并创建它(或重新编译它)并开始使用它。

What are the available options to identify and remove the invalid objects in Postgres (ex: corrupted indexes)

参见http://www.postgresql.org/docs/8.4/static/indexes-multicolumn.html