-- =====================================================================
|
-- service_subtask 索引优化脚本
|
-- 目标接口:POST /smartor/serviceSubtask/patItem(及共用同一套 SQL 的 /patItemCount、/patItemExport)
|
--
|
-- 涉及的两条 SQL(都在 ruoyi-task/src/main/resources/mapper/task/ServiceSubtaskMapper.xml):
|
-- 1) id = selectServiceSubtaskList —— 列表,约 100 列 + order by + limit offset
|
-- 2) id = countByCondition —— 同一套 where 的 SUM 聚合(Redis 未命中时执行)
|
--
|
-- 兼容性:MySQL 5.7 / 8.0 均可执行。
|
-- * 5.7 不支持降序索引,但 ASC 索引可被反向扫描,order by ... desc 同样能用,无需额外处理;
|
-- * 5.7 没有 EXPLAIN ANALYZE,验证用文末的 EXPLAIN + Handler 状态变量。
|
-- =====================================================================
|
|
-- ---------------------------------------------------------------------
|
-- 0. 执行前先看现状(避免重复建索引 / 确认数据量与列类型)
|
-- ---------------------------------------------------------------------
|
SHOW INDEX FROM service_subtask;
|
|
SELECT COUNT(*) AS total_rows FROM service_subtask;
|
|
SELECT COLUMN_NAME, COLUMN_TYPE
|
FROM information_schema.COLUMNS
|
WHERE TABLE_SCHEMA = DATABASE()
|
AND TABLE_NAME = 'service_subtask'
|
AND COLUMN_NAME IN ('orgid', 'campusid', 'del_flag', 'endtime',
|
'visit_time', 'sendstate', 'taskid', 'create_time',
|
'patid', 'inhospid', 'schedule_id', 'loop_count');
|
|
-- ---------------------------------------------------------------------
|
-- 1. 必加:列表主查询 / 聚合的公共前缀 + 排序
|
--
|
-- where 固定是 del_flag = 0 AND orgid = ? AND campusid = ?(Controller 强制注入)
|
-- order by 默认是 endtime asc/desc
|
-- → 命中后 order by 不再 filesort,且 limit 可以提前截断;
|
-- 同时让 countByCondition 从「全表扫描」降为「一个机构+院区的范围扫描」。
|
-- ---------------------------------------------------------------------
|
ALTER TABLE service_subtask
|
ADD INDEX idx_ss_org_cam_del_endtime (orgid, campusid, del_flag, endtime),
|
ALGORITHM = INPLACE, LOCK = NONE;
|
|
-- ---------------------------------------------------------------------
|
-- 2. 必加:按随访时间排序/筛选(sort=2/3/7/8,以及 startSendDateTime/endSendDateTime 区间)
|
-- 注:这两个区间条件已由 date_format(...) 改写为可走索引的范围比较。
|
-- ---------------------------------------------------------------------
|
ALTER TABLE service_subtask
|
ADD INDEX idx_ss_org_cam_del_vtime (orgid, campusid, del_flag, visit_time),
|
ALGORITHM = INPLACE, LOCK = NONE;
|
|
-- ---------------------------------------------------------------------
|
-- 3. 必加:状态页签(sendstateView → sendstate IN (1,2,3,5,7) / (6) / (4))
|
-- 用户最常点的就是「待随访 / 已完成 / 无需随访」三个 tab。
|
-- ---------------------------------------------------------------------
|
ALTER TABLE service_subtask
|
ADD INDEX idx_ss_org_cam_del_state_end (orgid, campusid, del_flag, sendstate, endtime),
|
ALGORITHM = INPLACE, LOCK = NONE;
|
|
-- ---------------------------------------------------------------------
|
-- 4. 建议:任务维度下钻(taskid 是这张表最高频的等值条件)
|
-- ---------------------------------------------------------------------
|
ALTER TABLE service_subtask
|
ADD INDEX idx_ss_org_cam_del_task (orgid, campusid, del_flag, taskid),
|
ALGORITHM = INPLACE, LOCK = NONE;
|
|
-- ---------------------------------------------------------------------
|
-- 5. 建议:create_time 区间
|
-- 供 selectServiceSubtaskListByCreateTime / selectServiceSubtaskListAgain 使用。
|
-- ---------------------------------------------------------------------
|
ALTER TABLE service_subtask
|
ADD INDEX idx_ss_org_cam_del_ctime (orgid, campusid, del_flag, create_time),
|
ALGORITHM = INPLACE, LOCK = NONE;
|
|
-- ---------------------------------------------------------------------
|
-- 6. 建议:患者 / 住院记录反查(患者端、再次随访、转科链路)
|
-- ---------------------------------------------------------------------
|
ALTER TABLE service_subtask
|
ADD INDEX idx_ss_patid (patid),
|
ALGORITHM = INPLACE, LOCK = NONE;
|
|
ALTER TABLE service_subtask
|
ADD INDEX idx_ss_inhospid (inhospid),
|
ALGORITHM = INPLACE, LOCK = NONE;
|
|
-- ---------------------------------------------------------------------
|
-- 7. 建议:任务组滚动调度(countActiveByScheduleIdAndLoop,跑得非常勤)
|
-- ---------------------------------------------------------------------
|
ALTER TABLE service_subtask
|
ADD INDEX idx_ss_sched_loop (schedule_id, loop_count),
|
ALGORITHM = INPLACE, LOCK = NONE;
|
|
-- ---------------------------------------------------------------------
|
-- 8. 可选:让 countByCondition 变成覆盖索引(索引内完成聚合,不回表)
|
-- 只有当 Redis 命中率低、统计接口仍然慢时才加。
|
-- 代价:service_subtask 写入频繁,多一个宽索引会加大写入开销。
|
-- ---------------------------------------------------------------------
|
-- ALTER TABLE service_subtask
|
-- ADD INDEX idx_ss_org_cam_del_state_excep (orgid, campusid, del_flag, sendstate, excep),
|
-- ALGORITHM = INPLACE, LOCK = NONE;
|
|
-- ---------------------------------------------------------------------
|
-- 9. 收尾:更新统计信息,让优化器立刻用上新索引
|
-- ---------------------------------------------------------------------
|
ANALYZE TABLE service_subtask;
|
|
-- =====================================================================
|
-- 验证(MySQL 5.7 可用)
|
-- =====================================================================
|
|
-- 9.1 列表主查询:期望 key = idx_ss_org_cam_del_endtime,Extra 里【没有】Using filesort
|
EXPLAIN
|
SELECT id, endtime
|
FROM service_subtask
|
WHERE del_flag = 0
|
AND orgid = '这里换成真实 orgid'
|
AND campusid = '这里换成真实 campusid'
|
ORDER BY endtime DESC
|
LIMIT 20 OFFSET 0;
|
|
-- 9.2 状态页签:期望 key = idx_ss_org_cam_del_state_end
|
EXPLAIN
|
SELECT id, endtime
|
FROM service_subtask
|
WHERE del_flag = 0
|
AND orgid = '这里换成真实 orgid'
|
AND campusid = '这里换成真实 campusid'
|
AND sendstate IN (1, 2, 3, 5, 7)
|
ORDER BY endtime DESC
|
LIMIT 20 OFFSET 0;
|
|
-- 9.3 实际扫描量对比(执行前后各跑一次,看 Handler_read_next 是否大幅下降)
|
FLUSH STATUS;
|
SELECT COUNT(1) FROM service_subtask
|
WHERE del_flag = 0 AND orgid = '这里换成真实 orgid' AND campusid = '这里换成真实 campusid';
|
SHOW SESSION STATUS LIKE 'Handler_read%';
|
|
-- =====================================================================
|
-- 回滚
|
-- =====================================================================
|
-- ALTER TABLE service_subtask DROP INDEX idx_ss_org_cam_del_endtime;
|
-- ALTER TABLE service_subtask DROP INDEX idx_ss_org_cam_del_vtime;
|
-- ALTER TABLE service_subtask DROP INDEX idx_ss_org_cam_del_state_end;
|
-- ALTER TABLE service_subtask DROP INDEX idx_ss_org_cam_del_task;
|
-- ALTER TABLE service_subtask DROP INDEX idx_ss_org_cam_del_ctime;
|
-- ALTER TABLE service_subtask DROP INDEX idx_ss_patid;
|
-- ALTER TABLE service_subtask DROP INDEX idx_ss_inhospid;
|
-- ALTER TABLE service_subtask DROP INDEX idx_ss_sched_loop;
|
-- ALTER TABLE service_subtask DROP INDEX idx_ss_org_cam_del_state_excep;
|