[pgsql-jp: 30152] Re: ユーザ定義型の検索
junji
junji @ gi.k.u-tokyo.ac.jp
2003年 6月 9日 (月) 04:59:24 JST
橋本です。
使用目的はユーザ定義型にbtreeを使った近傍検索です。
ある数に近いの前後10個のデータを得るというような検索です。
それを
a < 1 order by desc limit 5
a >= 1 order by asc limit 5
のようにして実現しようとしています。
backwardの説明を不十分だったので追加します。
backward でというのが順序に並べて
後ろ部分(同じ意味ですが、昇順にソートしたデータ列の後ろの方)ということ
ではなく、
Index Scan Backwardのことです。
Index Scan Backwardを使えば
ある数より小さいデータに対して、降順に並べるときにインデックスをつかえば
ソートする必要がないはずです。
たとえば、
i=1,2,3,4,5,5,6,6,7
のデータに対して、
i<4のデータを降順にするクエリーがあったとして
3,2,1
をソートせず、得られます。それは、btreeが双方向リストだからです。
確かに、INT型であれば、以下のようにインデックスをつかって降順に並べます。
test=# EXPLAIN SELECT * from test_int where a < 1 order by a desc limit 2;
QUERY PLAN
-------------------------------------------------------------------------------
------
Index Scan Backward using test_int_idx on test_int (cost=0.00..6.03
rows=2 wi
th=4)
Index Cond: (a < 1)
(2 rows)
しかし、ユーザ定義型だと
test=# EXPLAIN SELECT * from test_complex where a < '(1,2)' order by a desc;
QUERY PLAN
-------------------------------------------------------------------------------
----------
Sort (cost=6.14..6.15 rows=5 width=32)
Sort Key: a
-> Index Scan using test_cplx_ind2 on test_complex (cost=0.00..6.07 rows=5
width=32)
Index Cond: (a < '(1,2)'::complex)
(4 rows)
のようなことになります。
これは、1以下のデータを昇順にすべて取ってきて、ソートし、降順からlimitで2つ取ってきます。
Index Scan Backwardで直接、降順から2つ取ってこれるはずです。
しかし、postgresはやってくれません。なぜ?
確かに以下のクエリーのように、x > '(9900,9900)' order by x asc;では、
ソートしていないですが、
x < '(9900,9900)' order by x desc;の場合はIndex scan forward の次にソー
トを行います。
> =#
>
> =# explain select * from class1 where x > '(9900,9900)' order by x asc; QUERY PLAN
> ---------------------------------------------------------------------------------
> Index Scan using class1_x_index on class1 (cost=0.00..13.75 rows=500 width=16)
> Index Cond: (x > '(9900,9900)'::complex)
> (2 rows)
>
> =#
>
>
pgsql-jp メーリングリストの案内