我有一个历史传递闭包表,代表一棵树。
create table TRANSITIVE_CLOSURE
(
CHILD_NODE_ID number not null enable,
ANCESTOR_NODE_ID number not null enable,
DISTANCE number not null enable,
FROM_DATE date not null enable,
TO_DATE date not null enable,
constraint TRANSITIVE_CLOSURE_PK unique (CHILD_NODE_ID, ANCESTOR_NODE_ID, DISTANCE, FROM_DATE, TO_DATE)
);
这里有一些样本数据:
CHILD_NODE_ID | ANCESTOR_NODE_ID | DISTANCE
--------------------------------------------
1 | 1 | 0
2 | 1 | 1
2 | 2 | 0
3 | 1 | 2
3 | 2 | 1
3 | 3 | 0
很遗憾,我当前用于查找根节点的查询会导致全表扫描:
select *
from transitive_closure tc
where
distance = 0
and not exists (
select null
from transitive_closure tci
where tc.child_node_id = tci.child_node_id
and tci.distance <> 0
);
表面上看起来这并不是很贵,但当我接近100万行时,这个特定的查询开始变得棘手起来...特别是当它是一个抓取遗留支持的邻接树的视图的一部分时。
有没有更好的方法来查找传递闭包的根节点?我想重新编写我们所有旧的遗留代码,但我不能...所以我需要以某种方式建立邻接表。获取除根节点之外的所有内容很容易,那么有没有更好的方法?我的思考方式是否有问题?
在具有800k行的表上的查询计划。
OPERATION OBJECT_NAME OPTIONS COST
SELECT STATEMENT 2301
HASH JOIN RIGHT ANTI 2301
Access Predicates
TC.CHILD_NODE_ID=TCI.CHILD_NODE_ID
TABLE ACCESS TRANSITIVE_CLOSURE FULL 961
Filter Predicates
TCI.DISTANCE = 1
TABLE ACCESS TRANSITIVE_CLOSURE FULL 962
Filter Predicates
DISTANCE=0
tci.distance = tc.distance + 1
会有帮助吗? - Jordãotci.distance <> tc.distance
对查询计划没有影响(其成本为3178)。 - Jon Bristow