liusheng
4 天以前 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
-- ============================================================================
-- /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;