3

我需要加快这个查询:

SELECT * FROM mytable 
WHERE 'value' = ANY("citext_array_col") LIMIT 1;

其中citext_array_col是一个 citext 数组。我试图创建一个操作员类:

CREATE OPERATOR CLASS gin__citext_ops
FOR TYPE citext[] USING gin
AS

        OPERATOR        6       = (anyarray, anyarray),
        FUNCTION        1       citext_cmp (citext, citext),
        FUNCTION        2       ginarrayextract(anyarray, internal, internal),
        FUNCTION        3       ginqueryarrayextract(anyarray, internal, smallint, internal, internal, internal, internal),
        FUNCTION        4       ginarrayconsistent(internal, smallint, anyarray, integer, internal, internal, internal, internal),
        STORAGE         citext;

我可以用这个运算符类创建 GIN 索引,但它没用(set enable_seqscan = off规划器仍然使用顺序扫描)。我不知道 ginqueryarrayextract() & co。做,没有关于这个的文档。

我发现的是 GIN 索引的 intarray 扩展,但代码是 C 语言,我对 PG C 扩展不太熟悉......

有没有更聪明的方法来为这个查询创建索引?也许使用文本支持功能?

4

3 回答 3

5

CIText 的运算符类(改编自Florent Guillaume 建议的 uuid 数组上的 PostgreSQL GIN 索引)如下:

CREATE OPERATOR CLASS _citext_ops DEFAULT 
  FOR TYPE _citext USING gin AS 
  OPERATOR 1 &&(anyarray, anyarray), 
  OPERATOR 2 @>(anyarray, anyarray), 
  OPERATOR 3 <@(anyarray, anyarray), 
  OPERATOR 4 =(anyarray, anyarray), 
  FUNCTION 1 citext_cmp(citext, citext),
  FUNCTION 2 ginarrayextract(anyarray, internal, internal), 
  FUNCTION 3 ginqueryarrayextract(anyarray, internal, smallint, internal, internal, internal, internal), 
  FUNCTION 4 ginarrayconsistent(internal, smallint, anyarray, integer, internal, internal, internal, internal), 
  STORAGE citext;

此外,还需要根据 eeeebbbbrrrr 的建议修改查询:

SELECT * FROM mytable 
WHERE citext_array_col && ARRAY['value']::citext[];
于 2013-11-20T17:23:05.393 回答
2

uuid 数组上的 PostgreSQL GIN 索引给出了一个uuid可能适用于citext.

于 2013-11-13T16:59:05.467 回答
0

我相信你想要的是像这样声明操作符类:

     CREATE OPERATOR CLASS _citext_ops DEFAULT FOR TYPE citext[] USING gin
AS

        OPERATOR        3       && (anyarray, anyarray),
        OPERATOR        6       = (anyarray, anyarray),
        OPERATOR        7       @> (anyarray, anyarray),
        OPERATOR        8       <@ (anyarray, anyarray),
        FUNCTION        1       citext_cmp (citext, citext),
        FUNCTION        2       ginarrayextract(anyarray, internal, internal),
        FUNCTION        3       ginqueryarrayextract(anyarray, internal, smallint, internal, internal, internal, internal),
        FUNCTION        4       ginarrayconsistent(internal, smallint, anyarray, integer, internal, internal, internal, internal),
        STORAGE         citext;

然后您的查询将采用稍微不同的形式:

SELECT * FROM mytable 
WHERE citext_array_col && ARRAY['value']::citext[];

还要确保您已使用 gin 创建了正确的索引:

CREATE INDEX idxfoo ON mytable USING gin (citext_array_col);

这将找到 citext_array_col 在任何元素中包含“值”的所有行。“&&”运算符是重叠运算符。见http://www.postgresql.org/docs/9.3/static/functions-array.html

(编辑:类型-o)

于 2013-09-12T20:25:24.113 回答