具有异构数据类型的3个字段的多列索引

nou*_*ine 7 postgresql indexing postgis postgresql-performance

我有一个包含3个字段的postgres表:

  • a:postgis几何
  • b:array varchar []
  • c:整数

我有一个涉及所有这些问题的查询.我想添加一个多列索引来加速它,但我不能因为它们的性质而不能将3个字段放在同一个索引下.

这种情况下的策略是什么?添加3个索引gist,gin和btree以及postgres将在查询期间使用它们吗?

Erw*_*ter 8

单列索引

首先,Postgres可以在单个查询中使用位图索引扫描非常有效地组合多个索引.大多数情况下,Postgres将选择最具选择性的索引(或两个并将它们与位图索引扫描结合起来)并在位图堆扫描后过滤其余的索引.一旦结果集足够窄,扫描另一个索引就没有效率.

多列索引

拥有完美匹配的多列索引仍然更快,但不是数量级.
由于你想要包含一个数组类型,我建议使用GIN索引.对于数组类型的通用GiST索引,缺少AFAIK运算符类.(该例外是intarray用于integer阵列.)

要包含该integer列,首先安装附加模块btree_gin,该模块提供必要的GIN运算符类.每个数据库运行一次:

CREATE EXTENSION btree_gin;
Run Code Online (Sandbox Code Playgroud)

然后你应该能够创建你的多列索引:

CREATE INDEX tbl_abc_gin_idx ON tbl USING GIN(a, b, c);
Run Code Online (Sandbox Code Playgroud)

索引列的顺序与GIN索引无关.每个文件:

多列GIN索引可以与涉及索引列的任何子集的查询条件一起使用.与B-tree或GiST不同,无论查询条件使用哪个索引列,索引搜索有效性都是相同的.

最近邻搜索

由于您包含PostGis geometry类型,因此您可能希望进行最近邻搜索,您需要GiST索引.在这种情况下,我建议两个索引:

CREATE INDEX tbl_ac_gist_idx ON tbl USING GiST(a, c);  -- geometry type
CREATE INDEX tbl_bc_gin_idx  ON tbl USING GIN(b, c);
Run Code Online (Sandbox Code Playgroud)

您可以将integer列添加c到其中一个或两个.这取决于.对于这一点,你需要或者btree_ginbtree_gist分别或两者.