2011-11-18 46 views
2

我有一个非常严重的性能问题,我无法修复自己。如何在处理文本搜索和地理空间数据时影响Postgres查询分析器

特定情况下

  • 我有一个Postgres 8.4数据库在PostGIS 1.4安装
  • 我有〜9万个条目地理空间表。这个表有一个(PostGIS的)几何列和tsvector字段
  • 我对几何GIST指数和VNAME指数在VNAME列
  • ANALYZE倒是

我想excecute一个to_tsquery文本搜索在这些几何的子集应该给我所有影响的ID回来。

要搜索的区域会将9百万个数据集限制为大约100.000,并且该区域内的ts_query的结果集很可能会输出0..1000个条目。

问题

查询分析器决定,他要先做一个位图索引扫描的VNAME,然后aggreates并把过滤器上的几何形状(和其他条件我在此声明)

查询分析器输出:

Aggregate (cost=12.35..12.62 rows=1 width=510) (actual time=5.616..5.616 rows=1 loops=1) 
-> Bitmap Heap Scan on mxgeom g (cost=8.33..12.35 rows=1 width=510) (actual time=5.567..5.567 rows=0 loops=1) 
    Recheck Cond: (vname @@ '''hemer'' & ''hauptstrasse'':*'::tsquery) 
    Filter: (active AND (geom && '0107000020E6100000010000000103000000010000000B0000002AFFFF5FD15B1E404AE254774BA8494096FBFF3F4CC11E40F37563BAA9A74940490200206BEC1E40466F209648A949404DF6FF1F53311F400C9623C206B2494024EBFF1F4F711F404C87835954BD4940C00000B0E7CA1E4071551679E0BD4940AD02004038991E40D35CC68418BE49408EF9FF5F297C1E404F8CFFCB5BBB4940A600006015541E40FAE6468054B8494015040060A33E1E4032E568902DAE49402AFFFF5FD15B1E404AE254774BA84940'::geometry) AND (mandator_id = ANY ('{257,1}'::bigint[]))) 
    -> Bitmap Index Scan on gis_vname_idx (cost=0.00..8.33 rows=1 width=0) (actual time=5.566..5.566 rows=0 loops=1) 
      Index Cond: (vname @@ '''hemer'' & ''hauptstrasse'':*'::tsquery) 

导致的I/O很多 - 据我所知这将是更明智的,首先限制的几何形状,后做VNAME搜索。

尝试的解决方案

为了达到所期望的行为我试图

  1. 我把GEOM @@AREA成子查询 - >没有改变
  2. 我创建了一个执行计划临时视图与所需区域子集 - >没有更改执行计划
  3. 我创建了一个所需区域的临时表 - >需要4〜6秒才能创建,所以临时表使情况更糟。

顺便说一句,抱歉没有发布实际查询:我认为我的老板真的会生我的气,同时我正在寻找理论指针来解决我的实际查询问题。请询问您是否需要进一步澄清


编辑

理查德有一个非常好的问题:您可以实现查询规划与width语句的期望行为。坏事是这个临时表(或CTE)弄乱了vname索引,因此在某些情况下查询不会返回任何内容。

我能够解决这个问题,创建一个新的名称与to_tsvector()即时,但这是(太)昂贵 - 大约每个查询300-500毫秒。

我的解决方案

我抛弃了VNAME搜索,并用简单的LIKE('%query_string%')(10-20毫秒/查询)去了,但是这仅仅是快在我给定的环境。因人而异。

回答

2

tsvector的统计处理已经有了一些改进(我也认为PostGIS也是这样,但我没有使用它)。如果你有时间,可能值得再次尝试使用9.1版本,并看看它对你有什么作用。

但是,对于此单个查询,您可能需要查看WITH构造。

http://www.postgresql.org/docs/8.4/static/queries-with.html

如果你把几何一部分WITH子句,将首先评估(保证),然后该结果集将通过以下SELECT过滤。它可能最终会变慢,直到你尝试才会知道。

这可能是对work_mem的调整也会有所帮助 - 您可以按会话执行此操作(“SET work_mem = ...”),但要小心将其设置得太高 - 并发查询可以快速通过所有RAM 。

http://www.postgresql.org/docs/8.4/static/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY

+0

谢谢理查!正如我在编辑中所说的那样,with-contruct确实按预期编制了许多查询计划,但最终结果太慢了,我发现了一个解决方法。不幸的是,由于其他传统框架,我不能切换到9.1,这取决于8.4 :( –