postgres中大型数据库的索引

时间:2014-02-13 09:03:37

标签: postgresql indexing

我在postgres中有一张表,有大约200万条记录。我需要提供一些索引,以便为like %text%查询提供良好的性能。

我在某地读过Gin索引适合%text%次搜索,所以尝试了Gin和Gist索引,但不知道为什么没有这样的性能提升,而且Gin索引使用顺序扫描而不是堆扫描。

这是我的杜松子酒指数:

CREATE INDEX city_gin_idx_name
  ON city
  USING gin
  (to_tsvector('english'::regconfig, lower(name::text)));

查询效果:

  

“排序(成本= 117553.00..118496.71行= 377482宽度= 50)(实际   time = 1719.660..1745.702 rows = 35185 loops = 1)“”排序键:   (concat(name,',',state_name,',',country_name))“”排序方法:   外部合并磁盘:2200kB“” - > Seq扫描城市   (成本= 0.00..56777.75行= 377482宽度= 50)(实际   time = 0.392..1474.559 rows = 35185 loops = 1)“”过滤器:   ((lower((name):: text)~~'%ed%':: text)或((city_metaphone):: text =   'K':: text))“”由过滤器删除的行:1851806“”总运行时间:    1764.036 ms“

请告诉我这个要求的任何合适的索引。

1 个答案:

答案 0 :(得分:1)

您需要为该查询创建两个索引,并且需要在查询中使用完全相同的表达式来使用它们:

create index … on city using GIN (to_tsvector('english', name));
create index … on city (city_metaphone);

请注意,在第一个索引中小写名称是无用的,因为to_tsvector无论如何都会在计算向量时忽略该大小写。

然后查询需要看起来像这样,你应该得到一个使用位图索引扫描的计划:

select *
from city
where city_metaphone = 'K'
   or to_tsvector('english', name) @@ to_tsquery('english', 'Katmandu');

话虽如此,我认为你在这里使用全文是错误的。特别是,您的'%ed%'表示您希望全文可以让您进行某种LIKE比较。

这不是它开箱即用的方式,但是三元组将使它以这种方式工作:

http://www.postgresql.org/docs/current/static/pgtrgm.html