-- ============================================================================ -- /smartor/trace/tracedeallist(异常问题处理情况查询)性能优化配套索引 -- -- 改造后这条接口固定执行 5 条聚合 SQL,过滤条件都是: -- service_subtask_detail_trace: orgid + template_type + del_flag(+ 分组/排序 questiontext) -- service_subtask_detail: scriptid -- 线上如果这两张表没有对应索引,聚合仍然是全表扫描。 -- -- 执行顺序:先跑第 1 步看现状和字段类型,再按第 2 步加缺失的索引。 -- ADD INDEX 走 online DDL(不阻塞读写),但大表仍会吃 IO,建议业务低峰执行。 -- ============================================================================ -- ---------------------------------------------------------------------------- -- 第 1 步:看现有索引 + questiontext 的字段类型(决定能不能把 questiontext 放进索引) -- ---------------------------------------------------------------------------- SELECT INDEX_NAME, SEQ_IN_INDEX, COLUMN_NAME, NON_UNIQUE FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME IN ('service_subtask_detail_trace', 'service_subtask_detail') ORDER BY TABLE_NAME, INDEX_NAME, SEQ_IN_INDEX; SELECT TABLE_NAME, COLUMN_NAME, COLUMN_TYPE, CHARACTER_MAXIMUM_LENGTH FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME IN ('service_subtask_detail_trace', 'service_subtask_detail') AND COLUMN_NAME IN ('orgid', 'campusid', 'template_type', 'del_flag', 'scriptid', 'questiontext', 'handle_time', 'todeptcode'); SELECT TABLE_NAME, TABLE_ROWS, ROUND(DATA_LENGTH / 1024 / 1024, 1) AS data_mb FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME IN ('service_subtask_detail_trace', 'service_subtask_detail'); -- ---------------------------------------------------------------------------- -- 第 2 步:加索引(已存在的会报 Duplicate key name,跳过即可) -- ---------------------------------------------------------------------------- -- ① trace 表的主过滤条件:orgid + template_type + del_flag -- (本接口入参只有 templateType,orgid 由 @AddOrgId 注入) ALTER TABLE service_subtask_detail_trace ADD INDEX idx_trace_deal_query (orgid, template_type, del_flag); -- ② 明细表的「有效填写数」按 scriptid 统计(改造前是逐个 scriptid 查,改造后是一条 group by) ALTER TABLE service_subtask_detail ADD INDEX idx_detail_scriptid (scriptid); -- ③ 可选:如果第 1 步查到 questiontext 是 VARCHAR(255) 及以下(utf8mb4 不超过 255), -- 可以再加覆盖分组/排序的索引,效果更好: -- ALTER TABLE service_subtask_detail_trace -- ADD INDEX idx_trace_deal_group (orgid, template_type, del_flag, questiontext); -- ④ 可选:最新处理人那条 SQL 用到 (questiontext, handle_time) -- ALTER TABLE service_subtask_detail_trace -- ADD INDEX idx_trace_deal_handle (orgid, template_type, del_flag, questiontext, handle_time); -- ---------------------------------------------------------------------------- -- 第 3 步:验证索引是否生效(把下面 SQL 拿去 EXPLAIN,key 列应该命中刚建的索引) -- ---------------------------------------------------------------------------- -- EXPLAIN SELECT questiontext, min(scriptid), count(*) -- FROM service_subtask_detail_trace -- WHERE del_flag = 0 AND questiontext IS NOT NULL -- AND orgid = '20001001' AND template_type = 2 -- GROUP BY questiontext ORDER BY questiontext LIMIT 10 OFFSET 0; -- -- EXPLAIN SELECT scriptid, count(*) FROM service_subtask_detail -- WHERE scriptid IN (1, 2, 3) GROUP BY scriptid;