80 lines
4.2 KiB
Markdown
80 lines
4.2 KiB
Markdown
# 资金流图谱接口超时优化实施记录
|
|
|
|
## 背景
|
|
|
|
- 生产反馈:资金流图谱页面请求 `/ccdi/project/fund-graph/graph` 出现接口超时。
|
|
- 截图中的请求参数为 `keyword=330781199401056317`,属于身份证号精确查询场景。
|
|
- 生产数据量约 61 万主体时,原主体定位 SQL 将身份证精确匹配、姓名模糊匹配、`object_key` 精确匹配混在同一个 `OR` 条件内,并叠加 `ORDER BY CASE`,容易导致优化器选择低效执行计划。
|
|
|
|
## 修改内容
|
|
|
|
1. 拆分主体定位查询:
|
|
- 文件:`ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiFundGraphMapper.java`
|
|
- 文件:`ccdi-project/src/main/resources/mapper/ccdi/project/CcdiFundGraphMapper.xml`
|
|
- 新增 `selectFundGraphSubjectsByExactKeyword`,只查询 `idnocfno = keyword` 与 `object_key = keyword`。
|
|
- 新增 `selectFundGraphSubjectsByName`,仅在精确查询无结果后再执行 `name LIKE '%keyword%'`。
|
|
- `selectFundGraphSubjects` 保留为 `object_key` 主键查询,不再执行额外排序。
|
|
|
|
2. 调整 Service 调用顺序:
|
|
- 文件:`ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiFundGraphServiceImpl.java`
|
|
- `/search` 与 `/graph` 的中心节点解析统一走 `selectSubjects`。
|
|
- 有 `objectKey` 时直接主键查询。
|
|
- 无 `objectKey` 且有 `keyword` 时,先精确查询;精确命中后直接返回,不再执行姓名模糊查询。
|
|
|
|
3. 优化图谱边查询入口:
|
|
- 文件:`ccdi-project/src/main/resources/mapper/ccdi/project/CcdiFundGraphMapper.xml`
|
|
- 新增 `subjectJoinRowsByCenter`,将“中心主体作为起点”和“中心主体作为终点”拆为两段 `UNION ALL`。
|
|
- `selectFundGraphEdges` 改为引用 `subjectJoinRowsByCenter`,避免在主体表两侧使用 `from_subject.object_key OR to_subject.object_key` 作为过滤入口。
|
|
|
|
## 影响范围
|
|
|
|
- 资金流图谱主体搜索:`GET /ccdi/project/fund-graph/search`
|
|
- 资金流图谱查询:`GET /ccdi/project/fund-graph/graph`
|
|
- 边明细查询 `GET /ccdi/project/fund-graph/edge-detail` 仍使用原明细 SQL 片段,未改变入参和返回结构。
|
|
- 本次未新增数据库字段或索引脚本;现有 DDL 中已包含 `lx_fund_flow_subject_node.idnocfno`、`name` 和 `object_key` 相关索引。
|
|
|
|
## 验证情况
|
|
|
|
- 已通过静态断言确认:
|
|
- Mapper 与 XML 已新增精确查询和姓名查询方法。
|
|
- XML 中已移除 `OR n.name LIKE` 的精确/模糊混用形态。
|
|
- `selectFundGraphEdges` 已引用 `subjectJoinRowsByCenter` 且包含 `UNION ALL`。
|
|
- 已通过 XML 格式检查:
|
|
- `xmllint --noout ccdi-project/src/main/resources/mapper/ccdi/project/CcdiFundGraphMapper.xml`
|
|
- 已通过 MyBatis XML 解析和 SQL 渲染临时检查:
|
|
- `selectFundGraphSubjectsByExactKeyword`
|
|
- `selectFundGraphSubjectsByName`
|
|
- `selectFundGraphEdges`
|
|
- 已通过源码编译:
|
|
- `mvn -pl ccdi-project -am -DskipTests compile`
|
|
|
|
## 验证阻断说明
|
|
|
|
- 直接执行 `mvn -pl ccdi-project -DskipTests compile` 会使用本地仓库中的旧依赖模块,出现既有签名不一致错误;使用 `-am` 联编依赖模块后通过。
|
|
- 直接执行 `mvn -pl ccdi-project -Dtest=CcdiFundGraphTimeoutOptimizationTest test` 时,测试编译阶段被既有无关测试源码阻断,未进入本次临时测试断言:
|
|
- `CcdiBankStatementTest` 仍引用 `BankStatementItem#setCustomerCertNo`、`setCustomerSocialCreditCode`。
|
|
- `CcdiFileUploadServiceImplTest` 仍按旧的 `LsfxAnalysisClient.uploadFile(Integer, Object, String)` 签名编写。
|
|
|
|
## 生产核对建议
|
|
|
|
- 发布后用生产超时样例身份证号重新请求 `/ccdi/project/fund-graph/graph`,核对接口耗时与返回图谱中心节点。
|
|
- 如生产库是历史库,先确认以下索引存在:
|
|
|
|
```sql
|
|
SHOW INDEX FROM lx_fund_flow_subject_node WHERE Key_name IN (
|
|
'PRIMARY',
|
|
'idx_lx_fund_flow_subject_idnocfno',
|
|
'idx_lx_fund_flow_subject_name'
|
|
);
|
|
|
|
SHOW INDEX FROM lx_fund_flow_own_account_edge WHERE Key_name IN (
|
|
'idx_lx_fund_flow_own_from_key',
|
|
'idx_lx_fund_flow_own_to_key'
|
|
);
|
|
|
|
SHOW INDEX FROM lx_fund_flow_detail_edge WHERE Key_name IN (
|
|
'idx_lx_fund_flow_detail_from_date',
|
|
'idx_lx_fund_flow_detail_to_date'
|
|
);
|
|
```
|