[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 メーリングリストの案内