2013-02-24 62 views
3

我有一个非常简单的查询,基本上是这样的速度很慢查询(varchar 255)当匹配的文本字段不为空字符串

查询需要大约39,000ms才能运行。我在猜测,因为它不得不通过每个记录来查看非空字符串的事情。我已经索引了my_field列,但它没有改变任何东西。

万一它的任何使用,这里是查询计划:

"Seq Scan on my_table (cost=0.00..3468.91 rows=39744 width=459)" 
" Filter: ((my_field)::text <> ''::text)" 

什么,这里是我最好的选择?

解释分析:

"Seq Scan on my_table (cost=0.00..3468.91 rows=39730 width=459) (actual time=0.021..13.763 rows=39714 loops=1)" 
" Filter: ((my_field)::text <> ''::text)" 
"Total runtime: 14.856 ms" 

我添加了这些指标

CREATE INDEX aa_idx ON my_table(my_field); 
CREATE INDEX aa_idx ON my_table(my_field) WHERE my_field <> ''; 

它的Postgres 9.1

编辑:2013年2月26日00:04GMT]

在“m”上创建分区会有什么好处吗? y_field“作为检查约束?

像CHECK(my_field =“”)和分区2 CHECK(my_field!=“”)

我猜那么我就必须是一个有很多在这行的表?但是,这意味着即使分区将包含大约80%的数据,select!=''查询的执行速度也会快得多吗?

我也看了全文搜索,但这似乎是一个OTT。我也看着使列为0或1(布尔)的int,但这对性能没有影响(我猜因为= 1仍然带回很多行?)

+0

1)具有(非)空my_field的记录的概率是多少:有多少记录满足条件? 2)你是否有统计数据(你是否在添加索引后运行'vacuum analyze')? – wildplasser 2013-02-24 23:34:04

+0

1)通常情况下,我会说大约75%的字段与查询匹配。2)是的,我之后进行了真空全分析。我也尝试添加my_field <>''的部分索引,但没有任何区别。 – TheStoneFox 2013-02-24 23:39:36

+0

最好显示'解释分析'不只是简单的'解释'。另外:PostgreSQL版本?你的数据库在哪个区域?并请显示您添加的索引的定义。 – 2013-02-24 23:41:47

回答

2

索引不会帮助你。我认为你需要找到一个更好的方法来整合你的删除。

您说它运行需要39秒,但您提供的实际查询计划需要15毫秒才能运行,这大约是2000年的一个因子。除非我们正在讨论带有大量TOASTed值的非常宽泛的表格,否则我很难想象缓存会有多大帮助。这告诉我实际的问题不在你的选择中,而是在你的管道中的其他地方。这可能包括往返费用,但是您正在执行删除操作。

我的建议是看看声明合并。这将意味着避免往返并尽可能多地将逻辑推入单个查询中。既然你还没有发布完整的上下文,我建议你可能希望查看可写CTE的批处理插入,更新和删除一起没有往返旅程。