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