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

Posted

技术标签:

【中文标题】具有异构数据类型的 3 个字段的多列索引【英文标题】:Multicolumn index on 3 fields with heterogenous data types 【发布时间】:2014-05-04 17:00:34 【问题描述】:

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

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

我有一个涉及所有这些的查询。我想添加一个多列索引以加快速度,但我不能,因为这 3 个字段由于它们的性质而不能位于同一索引下。

这种情况下的策略是什么?添加 3 个索引 gist、gin 和 btree 和 postgres 会在查询期间全部使用吗?

【问题讨论】:

你能显示有问题的表和查询,以及explain analyze吗? 【参考方案1】:

这 3 个字段因其性质而不能归于同一索引下

哦yes they can。

【讨论】:

哦,我明白了...我无法了解如何创建多列索引 :( 你可以吗?它只显示:CREATE INDEX testidx ON test USING gist (a); 但那不是多列,是吗? 如果您只是 (1) 加载扩展程序并 (2) 像通常那样使用列出的多个列创建它,它不会工作吗? 哦,好吧,所以我需要加载一个扩展才能做到这一点。现在一切都清楚了。谢谢。【参考方案2】:

单列索引

Postgres 可以通过位图索引扫描在单个查询中非常有效地组合多个索引。大多数时候,选择最具选择性的索引(或两个,结合位图索引扫描),其余的被过滤。一旦结果集足够窄,扫描更多索引就没有效率了。

多列索引

拥有完美匹配的multicolumn index 仍然更快,但不是数量级。 由于您想包含 数组类型,我建议使用 GIN 索引。 AFAIK,数组类型的通用 GiST 索引缺少运算符类。 (intarray 数组的例外是 integer。)

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

CREATE EXTENSION btree_gin;

那么你应该能够创建你的多列索引:

CREATE INDEX tbl_abc_gin_idx ON tbl USING GIN(a, b, c);

索引列的顺序与 GIN 索引无关。 The manual:

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

最近邻搜索

由于您包含 PostGis geometry 类型,因此您很可能想做一个 nearest neighbour search,为此您需要一个 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);

您可以将integerc 添加到其中一个或两个中。这取决于。 为此,您需要 btree_ginbtree_gist 或两者。

【讨论】:

以上是关于具有异构数据类型的 3 个字段的多列索引的主要内容,如果未能解决你的问题,请参考以下文章

sap表字段最多有几个

MySQL索引

MySQL笔记2.6索引

MySQL数据库的索引类型

数据库索引- 多列索引

练习题|MySQL