liusheng
5 天以前 fb89df539c6293a41933e445df25fa9b8047ba18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
-- =====================================================================================
-- 诊断:admin 登录/创建任务时看不到全部科室病区 + belongDepts/belongWards 查询慢
-- 日期:2026-11-06   库:smartor_nhfy(192.168.99.192:3306)
--
-- 代码链路(已确认):
--   GET /getInfo            → SysLoginController#getInfo(L243-254)
--                                 → ISysDeptService#selectLeafSysDeptListBySysUserDept
--   GET /system/user/getInfo → SysUserController#getInfo(L151-165),同样两行
--                                 → SysDeptServiceImpl#selectLeafSysDeptListBySysUserDept(L335-341)
--                                     → SysDeptMapper#selectSysDeptListBySysUserDept(SysDeptMapper.xml L286-298)
--                                         → TreeUtils.getLeafDepts(只留叶子)
--   前端「创建任务」的科室/病区下拉就是用这两个返回的 belongDepts / belongWards。
--
-- 关键点(同一段 SQL 同时造成「看不到」和「慢」):
--   1) 列表来自 sys_dept INNER JOIN sys_user_dept ON dept_code ⇒ 只有「至少被某个用户关联过」的
--      科室/病区才会出现;admin 在 /getInfo 里同样带 userId,等于只看自己被分配的部门。
--   2) 该 SQL 还带 `and d.campusid = 登录用户院区`(L295),sys_dept.campusid 为空或与登录院区
--      不一致的部门会被过滤掉。
--   3) 结果再过 TreeUtils.getLeafDepts,凡是「被别的部门当成 parent_id」的部门都不返回。
--   4) 慢:admin 分支(SysUserServiceImpl#selectLeafSysDeptForAdmin)不带 userId,
--      这条 join 就变成「科室 × 关联该科室的所有用户」的笛卡尔放大;两个查询串行、每行还要
--      BeanUtils.copyProperties 转一次、还被包在 50 秒超时里。
-- =====================================================================================
 
-- 1. admin 在 sys_user_dept 里到底有多少条关系(少 → 下拉就少)
SELECT u.user_id, u.user_name, u.orgid, u.campusid, u.searchscope,
       (SELECT COUNT(*) FROM sys_user_dept ud
         WHERE ud.user_id = u.user_id AND ud.del_flag = '0' AND ud.dept_type = '1') AS ks_cnt,
       (SELECT COUNT(*) FROM sys_user_dept ud
         WHERE ud.user_id = u.user_id AND ud.del_flag = '0' AND ud.dept_type = '2') AS bq_cnt
FROM sys_user u
WHERE u.user_name IN ('admin')          -- 换成实际登录账号
   OR u.user_id IN (SELECT ud.user_id FROM sys_user_dept ud GROUP BY ud.user_id ORDER BY COUNT(*) DESC LIMIT 5);
 
-- 2. 该机构「应该有」多少科室/病区(sys_dept 全量)
SELECT orgid, dept_type, COUNT(*) AS rows_, COUNT(DISTINCT dept_code) AS codes
FROM sys_dept
WHERE del_flag = '0' AND orgid = '20001001'      -- 换成实际 orgid
GROUP BY orgid, dept_type;
 
-- 3. 「能查出来」多少:join 后 + 带 campusid 过滤,对比第 2 步,差多少就是丢了多少
SELECT '整体(不限院区)' AS scope, d.dept_type,
       COUNT(*) AS join_rows, COUNT(DISTINCT d.dept_code) AS dept_codes,
       COUNT(DISTINCT d.dept_id) AS dept_ids
FROM sys_dept d
         INNER JOIN sys_user_dept ud ON d.dept_code = ud.dept_code
WHERE d.del_flag = '0' AND ud.del_flag = '0'
  AND d.orgid = '20001001' AND ud.orgid = '20001001'
GROUP BY d.dept_type
UNION ALL
SELECT CONCAT('限院区 ', u.campusid) AS scope, d.dept_type,
       COUNT(*), COUNT(DISTINCT d.dept_code), COUNT(DISTINCT d.dept_id)
FROM sys_dept d
         INNER JOIN sys_user_dept ud ON d.dept_code = ud.dept_code
         JOIN sys_user u ON u.user_id = ud.user_id
WHERE d.del_flag = '0' AND ud.del_flag = '0'
  AND d.orgid = '20001001' AND ud.orgid = '20001001'
  AND d.campusid = u.campusid
GROUP BY u.campusid, d.dept_type;
 
-- 4. campusid 是否对不上(sys_dept 侧为空 / 与登录院区不同)
SELECT IFNULL(d.campusid, '(NULL)') AS dept_campusid, d.dept_type, COUNT(*) AS rows_
FROM sys_dept d
WHERE d.del_flag = '0' AND d.orgid = '20001001'
GROUP BY d.campusid, d.dept_type
ORDER BY rows_ DESC;
 
-- 5. 叶子过滤会丢掉多少(同一 dept_type 内,有子部门的部门不算叶子)
SELECT d.dept_type,
       COUNT(*) AS all_rows,
       SUM(CASE WHEN EXISTS (SELECT 1 FROM sys_dept c
                              WHERE c.parent_id = d.dept_id AND c.del_flag = '0') THEN 1 ELSE 0 END) AS not_leaf,
       SUM(CASE WHEN NOT EXISTS (SELECT 1 FROM sys_dept c
                              WHERE c.parent_id = d.dept_id AND c.del_flag = '0') THEN 1 ELSE 0 END) AS leaf
FROM sys_dept d
WHERE d.del_flag = '0' AND d.orgid = '20001001'
GROUP BY d.dept_type;
 
-- 6. 慢的量化:这条 join 每次都返回多少行(行数就是传输量 + BeanUtils 转换次数)
SELECT COUNT(*) AS join_rows_without_user
FROM sys_dept d
         INNER JOIN sys_user_dept ud ON d.dept_code = ud.dept_code
WHERE d.del_flag = '0' AND ud.del_flag = '0'
  AND d.orgid = '20001001' AND ud.orgid = '20001001'
  AND d.dept_type = '1';
-- 期望:远大于 sys_dept 里科室真实条数。这就是 admin 分支慢(selectLeafSysDeptForAdmin)的全部原因。
 
-- 7. 相关索引现状(下面建议的索引缺哪个补哪个)
SELECT table_name, index_name, seq_in_index, column_name
FROM information_schema.statistics
WHERE table_schema = DATABASE() AND table_name IN ('sys_dept', 'sys_user_dept')
ORDER BY table_name, index_name, seq_in_index;
 
-- 8. 建议索引(先看 7 再执行)
-- ALTER TABLE sys_user_dept ADD INDEX idx_sud_code_org_type (dept_code, orgid, dept_type, del_flag, user_id);
-- ALTER TABLE sys_user_dept ADD INDEX idx_sud_user_type (user_id, dept_type, orgid, del_flag, dept_code);
-- ALTER TABLE sys_dept      ADD INDEX idx_sd_org_type_campus (orgid, dept_type, campusid, del_flag, dept_code);
-- ALTER TABLE sys_dept      ADD INDEX idx_sd_code_org (dept_code, orgid, del_flag);
 
-- 9. 修完后自检:admin 应该能看到该机构全部科室/病区(数量等于第 2 步的 codes)
SELECT d.dept_type, COUNT(DISTINCT d.dept_code) AS visible_codes
FROM sys_dept d
WHERE d.del_flag = '0' AND d.orgid = '20001001'
  AND (d.campusid IS NULL OR d.campusid = '30001002')   -- 与登录院区保持一致
GROUP BY d.dept_type;