PostgreSQL 使用 GIN 的 int4range 索引数组 - 自定义运算符类

Posted

技术标签:

【中文标题】PostgreSQL 使用 GIN 的 int4range 索引数组 - 自定义运算符类【英文标题】:PostgreSQL index array of int4range using GIN - custom operator class 【发布时间】:2013-07-29 06:24:18 【问题描述】:

这是我的桌子:

CREATE TABLE
        mytable
        (
                id      INT NOT NULL PRIMARY KEY,
                val     int4range[]
        );

我要索引 val 列:

CREATE INDEX
    ix_mytable_val
ON      mytable
USING   GIN (INT4RANGE(val, '[]'));   // error, as is GIN(val)

我想出了以下内容:

CREATE OPERATOR CLASS gin_int4range_ops
DEFAULT FOR TYPE int4range[] USING gin AS
OPERATOR        1       <(anyrange,anyrange),
OPERATOR        2       <=(anyrange,anyrange),
OPERATOR        3       =(anyrange,anyrange),
OPERATOR        4       >=(anyrange,anyrange),
OPERATOR        5       >(anyrange,anyrange),
FUNCTION        1       lower(anyrange),
FUNCTION        2       upper(anyrange),
FUNCTION        3       isempty(anyrange),
FUNCTION        4       lower_inc(anyrange),
FUNCTION        5       upper_inc(anyrange);

但是当我尝试创建索引时,它失败了(下面的错误)。但是,如果我从 DO $$ 块中调用 create,它就会执行。

如果执行创建索引,我会在 INSERT INTO 上收到错误。

“错误:类型 1 的缓存查找失败”

我也试过这个:

OPERATOR        1       &&(anyrange,anyrange),
OPERATOR        2       <@(anyrange,anyrange),
OPERATOR        3       @>(anyrange,anyrange),
OPERATOR        4       =(anyrange,anyrange),

为了尝试解决这个问题,我重新启动了 PG,机器,并清理了 DB。我认为 CREATE OPERATOR 代码中存在错误。

如果我可以索引一个自定义类型 (int, int4range) 的数组,那就更好了。

我花了相当长的时间(一整天)翻阅文档、论坛等,但找不到真正帮助我理解如何解决这个问题的东西(即创建一个有效的自定义操作符类)。

【问题讨论】:

【参考方案1】:

你需要在Range Functions and Operators的基础上CREATE OPERATOR CLASS,例如:

   CREATE OPERATOR CLASS gin_int4range_ops
    DEFAULT FOR TYPE int4range[] USING gin AS
        OPERATOR        1       =(anyrange,anyrange),
        FUNCTION        1       lower(anyrange),
        FUNCTION        2       upper(anyrange),
        FUNCTION        3       isempty(anyrange),
        FUNCTION        4       lower_inc(anyrange),
        FUNCTION        5       upper_inc(anyrange);

现在你可以CREATE INDEX

CREATE INDEX ix_mytable4_vhstore_low
ON mytable USING gin (val gin_int4range_ops);

另请查看:Operator Classes and Operator FamiliesCREATE OPERATOR CLASS

以下查询显示所有已定义的运算符类:

SELECT am.amname AS index_method,
       opc.opcname AS opclass_name
    FROM pg_am am, pg_opclass opc
    WHERE opc.opcmethod = am.oid
    ORDER BY index_method, opclass_name;

此查询显示所有已定义的运算符系列以及每个系列中包含的所有运算符:

SELECT am.amname AS index_method,
       opf.opfname AS opfamily_name,
       amop.amopopr::regoperator AS opfamily_operator
    FROM pg_am am, pg_opfamily opf, pg_amop amop
    WHERE opf.opfmethod = am.oid AND
          amop.amopfamily = opf.oid
    ORDER BY index_method, opfamily_name, opfamily_operator;

【讨论】:

非常感谢!当我尝试创建索引时,我收到“错误:类型 1 的缓存查找失败”。我确实重新启动了服务器。有什么想法吗? 我已经尝试了所有我能想到的方法,但仍然出现该错误。 并非如此。我正在运行 Windows,而不是 Linux。我已经完成了完全重启,并通过分析完全真空。这可能与代码本身有关吗? 如果我将 CREATE INDEX 放在 DO $$ 块中,那么它将运行。但在这种情况下,INSERT INTO 会抛出同样的错误。 根据Table 35-6. GIN Array Strategies当前操作符类函数不正确。

以上是关于PostgreSQL 使用 GIN 的 int4range 索引数组 - 自定义运算符类的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 未对 JSONB 上的 GIN 索引使用索引扫描

PostgreSql jsonb 列上的 GIN 索引未在查询中使用

postgresqL 的Btree 与gin索引

PostgreSQL - 来自许多表和OR条件的字段的gin索引

PostgreSQL 使用 GIN 的 int4range 索引数组 - 自定义运算符类

此查询的 Postgresql 索引?