From c8571f9d5fde254d1ada6c1c4b762c038da5141c Mon Sep 17 00:00:00 2001 From: root Date: Thu, 30 Apr 2026 15:16:19 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20removeOrphanNodes=20O(N=C2=B2)=20?= =?UTF-8?q?=E2=86=92=20O(N)=20=E6=89=B9=E9=87=8F=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 改为先批量查询所有 active 关系的节点 ID 集合 - 再遍历所有节点找出孤儿节点 - 从 O(N×2) 查询降到 O(1) 批量 + O(N) 遍历 - 显著提升 cleanup / purge 性能 --- entry/src/main/ets/model/GraphDatabase.ets | 50 +++++++++++----------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/entry/src/main/ets/model/GraphDatabase.ets b/entry/src/main/ets/model/GraphDatabase.ets index abb4fe3..b1c4a8e 100644 --- a/entry/src/main/ets/model/GraphDatabase.ets +++ b/entry/src/main/ets/model/GraphDatabase.ets @@ -576,34 +576,36 @@ export class GraphDatabase { private async removeOrphanNodes(): Promise { if (!this.store) return 0; let deleted = 0; - const predicates: relationalStore.RdbPredicates = new relationalStore.RdbPredicates('nodes'); - const resultSet: relationalStore.ResultSet = await this.store.query(predicates, ['id', 'name']); - const nodesToCheck: number[] = []; - while (resultSet.goToNextRow()) { - nodesToCheck.push(resultSet.getLong(resultSet.getColumnIndex('id'))); + // 优化:批量查询所有有关系的节点 ID,避免 O(N²) 逐节点检查 + const activeRelPred: relationalStore.RdbPredicates = new relationalStore.RdbPredicates('relations'); + activeRelPred.equalTo('status', 'active'); + const relResultSet: relationalStore.ResultSet = await this.store.query(activeRelPred, ['subject_id', 'object_id']); + const relatedIds = new Set(); + while (relResultSet.goToNextRow()) { + relatedIds.add(relResultSet.getLong(relResultSet.getColumnIndex('subject_id'))); + relatedIds.add(relResultSet.getLong(relResultSet.getColumnIndex('object_id'))); } - resultSet.close(); + relResultSet.close(); - for (const nodeId of nodesToCheck) { - const pred1: relationalStore.RdbPredicates = new relationalStore.RdbPredicates('relations'); - pred1.equalTo('subject_id', nodeId); - const rs1 = await this.store.query(pred1, ['id']); - const hasSourceRel = rs1.goToFirstRow(); - rs1.close(); - - const pred2: relationalStore.RdbPredicates = new relationalStore.RdbPredicates('relations'); - pred2.equalTo('object_id', nodeId); - const rs2 = await this.store.query(pred2, ['id']); - const hasTargetRel = rs2.goToFirstRow(); - rs2.close(); - - if (!hasSourceRel && !hasTargetRel) { - const deletePred: relationalStore.RdbPredicates = new relationalStore.RdbPredicates('nodes'); - deletePred.equalTo('id', nodeId); - await this.store.delete(deletePred); - deleted++; + // 查询所有节点,筛选出不在关系中的孤儿节点 + const nodePred: relationalStore.RdbPredicates = new relationalStore.RdbPredicates('nodes'); + const nodeResultSet: relationalStore.ResultSet = await this.store.query(nodePred, ['id']); + const orphanIds: number[] = []; + while (nodeResultSet.goToNextRow()) { + const nodeId = nodeResultSet.getLong(nodeResultSet.getColumnIndex('id')); + if (!relatedIds.has(nodeId)) { + orphanIds.push(nodeId); } } + nodeResultSet.close(); + + // 批量删除孤儿节点 + for (const orphanId of orphanIds) { + const deletePred: relationalStore.RdbPredicates = new relationalStore.RdbPredicates('nodes'); + deletePred.equalTo('id', orphanId); + await this.store.delete(deletePred); + deleted++; + } return deleted; }