階層問い合わせ(start with ~~connect by)でrecursive callsとsorts (memory)がすごい大きい数字になる
900435Nov 15 2011 — edited Nov 16 2011次のような条件で検証を行いました。
例)
create table GROUP
(
id number(32) not null,
name varchar2(512) not null,
parent number(32) null,
constraint PK_GROUP primary key(id) using index
pctfree 5
initrans 5
maxtrans 255
tablespace ~~
storage(initial ~~~)
);
create index GROUPPARENTIDX on GROUP(parent)
pctfree 5
initrans 5
maxtrans 255
tablespace ~~~
storage(initial ~~~);
GROUPテーブルには、4000レコード入っている。
このテーブルは組織階層を表していて、ツリー状になっている。
ある特定のIDから、ルートの組織まで、再帰的に全てのIDを取得したい。
IDは対象レコード(組織)のID、PARENTは対象レコード(組織)の親の組織を表す。
この事から次のようなSQLで実現しようとしました。
select id from group start with id = 1127417 connect by prior PARENT = id;
取得されるレコード数は、5行です。
この結果の実行計画、及び統計情報は以下の通りです。
実行計画
----------------------------------------------------------
Plan hash value: 1702849243
-----------------------------------------------------------------
-------------
| Id | Operation | Name | Rows | Byt
)| Time |
-----------------------------------------------------------------
-------------
| 0 | SELECT STATEMENT | | 2 |
)| 00:00:01 |
|* 1 | CONNECT BY WITH FILTERING | | |
| |
| 2 | TABLE ACCESS BY INDEX ROWID | GROUP | 1 |
)| 00:00:01 |
|* 3 | INDEX UNIQUE SCAN | PK_GROUP | 1 |
)| 00:00:01 |
| 4 | NESTED LOOPS | | 1 |
)| 00:00:01 |
| 5 | CONNECT BY PUMP | | |
| |
| 6 | TABLE ACCESS BY INDEX ROWID| GROUP | 1 |
)| 00:00:01 |
|* 7 | INDEX UNIQUE SCAN | PK_GROUP | 1 |
)| 00:00:01 |
-----------------------------------------------------------------
-------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("ID"=PRIOR "PARENT")
3 - access("ID"=1127417)
7 - access("connect$_by$_pump$_002"."prior PARENT "="ID")
統計
----------------------------------------------------------
456 recursive calls
0 db block gets
103 consistent gets
28 physical reads
0 redo size
578 bytes sent via SQL*Net to client
420 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
13 sorts (memory)
0 sorts (disk)
5 rows processed
この事を以て、以下のような懸念点が生まれました。
・recursive callsがあまりにも大きい。(5行だけ扱っているようには見えないが、データとしては正しい)
・sorts (memory)が大きい。sortに関しては何も指定していない。
この状況が理解できず、いくら調べても改善する方法が見つかりません。
そもそも、
・このSQLが悪いのか
・oracleとしてはこれが普通なのか
等の事も切り分けができずにいます。
何かよいアドバイスを頂けないでしょうか。
以上です。
よろしくお願いします。