-- ===================================================================================== -- 诊断: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;