[pgsql-jp: 31841] Re: 配列要素の項目をCREATE  INDEXで指定する方法

Tatsuo Ishii t-ishii @ sra.co.jp
2003年 12月 18日 (木) 19:23:26 JST


石井です.

> > やりたいことが良く分からないのですが,たとえばどういうSELECT文のときに
> > インデックスが使えるようになることを期待しているのでしょうか?
> 
> 通常のSELECT分で
> WHERE shimebi[1] = 31 OR  shimebi[1] = 31 OR shimebi[2] = 31
> と、するつもりです。
> ただ、この構文でよいか否か、まだ、テストできておりません。
> 項目を配列にすべき理由は特になく、プログラムの内部処理上、
> 配列にしておきたいからです。
> 従いまして、shimebi1,shimebi2,shimebi3でも、かまわないことは
> ないのですが。

ああ,そういうことですか.これだとちょっと一工夫が要りますね.普通に配
列要素に対してインデックスを作ろうとすると,

test=# create index t11index on t1(i[1]);
ERROR:  parser: parse error at or near "[" at character 30

となってしまうのは先刻ご承知の通りです.これを回避するには,関数を作っ
てその関数にインデックスを貼ります.以下に例を示します.

drop table t1;
DROP TABLE
create table t1(i int[]);
CREATE TABLE
insert into t1 values('{1,2}');
INSERT 217068 1
insert into t1 values('{2,3}');
INSERT 217069 1
insert into t1 values('{3,4}');
INSERT 217070 1
insert into t1 values('{1,5}');
INSERT 217071 1
create or replace function f1(int[]) returns int as 'select $1[1]' language 'sql' immutable;
CREATE FUNCTION
create or replace function f2(int[]) returns int as 'select $1[2]' language 'sql' immutable;
CREATE FUNCTION
create index t11index on t1(f1(i));
CREATE INDEX
create index t12index on t1(f2(i));
CREATE INDEX
set enable_seqscan to off;
SET
explain select * from t1 where f1(i) = 2 or f2(i) = 2;
                                  QUERY PLAN                                  
------------------------------------------------------------------------------
 Index Scan using t11index, t12index on t1  (cost=0.00..9.38 rows=1 width=32)
   Index Cond: ((f1(i) = 2) OR (f2(i) = 2))
(2 rows)

select * from t1 where f1(i) = 2 or f2(i) = 2;
   i   
-------
 {2,3}
 {1,2}
(2 rows)

7.4では上のSELECT文と同じことを

select * from t1 where 2 = any(i);

とスマートに書けますが,残念ながらインデックスはききません.ですから,
7.4でも上のようなhackが必要になります.
--
Tatsuo Ishii



pgsql-jp メーリングリストの案内