2013-08-06 65 views
3

我需要加速比此查询:的PostgreSQL 9.2:上citext GIN索引[]

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扩展...

是否有创建这个索引的明智之选查询?也许使用文本支持功能?

回答

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[]; 

还要确保你所创建的正确使用索引杜松子酒:

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型)

+0

FYI此将不会按原样工作。 OPERATOR之后的数字是策略,对于仅使用策略1-4的GIN它们是错误的。请参阅http://www.postgresql.org/docs/9.2/static/xindex.html#XINDEX-STRATEGIES 看来,列出的策略是针对GiST的策略。 –

+0

这解决了我的问题,与uuid答案一起。非常感谢! – vad

4

为CIText(改编自PostgreSQL GIN index on array of uuid通过弗洛朗纪尧姆所建议的)操作员类如下:

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[];