优化GetStoreRemainingRights性能索引.sql
6.61 KB
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
-- ============================================
-- 优化 GetStoreRemainingRights 方法性能的索引
-- ============================================
-- 说明:这些索引专门为统计门店剩余权益功能优化
-- 执行前请检查索引是否已存在,避免重复创建
-- ============================================
-- 1. lq_kd_pxmx (开单品项明细表) 索引
-- ============================================
-- 用于:查询开单品项总数、按会员分组统计、JOIN关联
-- 查询条件:F_IsEffective, F_MemberId, glkdbh
-- 索引1:用于F_MemberId IN查询和JOIN
-- MySQL 5.7以下版本请先检查索引是否存在,或直接执行(如果已存在会报错,可忽略)
CREATE INDEX idx_kd_pxmx_member_effective_glkdbh
ON lq_kd_pxmx(F_IsEffective, F_MemberId, glkdbh);
-- 索引2:用于JOIN和按会员分组(补充索引,覆盖JOIN场景)
CREATE INDEX idx_kd_pxmx_glkdbh_member_effective
ON lq_kd_pxmx(glkdbh, F_MemberId, F_IsEffective);
-- ============================================
-- 2. lq_kd_kdjlb (开单记录表) 索引
-- ============================================
-- 用于:按门店和时间范围过滤、JOIN关联
-- 查询条件:F_IsEffective, djmd, kdrq
-- 索引1:用于门店+时间范围查询(最常用)
CREATE INDEX idx_kd_kdjlb_store_date_effective
ON lq_kd_kdjlb(djmd, kdrq, F_IsEffective);
-- 索引2:用于JOIN(补充,F_Id是主键可能不需要)
-- 如果F_Id是主键,则不需要此索引
-- CREATE INDEX IF NOT EXISTS idx_kd_kdjlb_id_effective
-- ON lq_kd_kdjlb(F_Id, F_IsEffective);
-- ============================================
-- 3. lq_xh_pxmx (消耗品项明细表) 索引
-- ============================================
-- 用于:查询消耗品项总数、按会员分组统计、JOIN关联
-- 查询条件:F_IsEffective, F_MemberId, F_ConsumeInfoId
-- 索引1:用于F_MemberId IN查询和JOIN
CREATE INDEX idx_xh_pxmx_member_effective_consume
ON lq_xh_pxmx(F_IsEffective, F_MemberId, F_ConsumeInfoId);
-- 索引2:用于JOIN场景(补充索引)
CREATE INDEX idx_xh_pxmx_consume_member_effective
ON lq_xh_pxmx(F_ConsumeInfoId, F_MemberId, F_IsEffective);
-- ============================================
-- 4. lq_xh_hyhk (消耗会员耗卡表) 索引
-- ============================================
-- 用于:按门店和时间范围过滤、JOIN关联
-- 查询条件:F_IsEffective, md, hksj
-- 索引1:用于门店+时间范围查询(最常用)
CREATE INDEX idx_xh_hyhk_store_date_effective
ON lq_xh_hyhk(md, hksj, F_IsEffective);
-- 索引2:用于JOIN(F_Id是主键则不需要)
-- CREATE INDEX IF NOT EXISTS idx_xh_hyhk_id_effective
-- ON lq_xh_hyhk(F_Id, F_IsEffective);
-- ============================================
-- 5. lq_hytk_hytk (退卡记录表) 索引
-- ============================================
-- 用于:按门店和时间范围过滤、JOIN关联
-- 查询条件:F_IsEffective, md, tksj
-- 索引1:用于门店+时间范围查询(最常用)
CREATE INDEX idx_hytk_hytk_store_date_effective
ON lq_hytk_hytk(md, tksj, F_IsEffective);
-- 索引2:用于JOIN(F_Id是主键则不需要)
-- CREATE INDEX IF NOT EXISTS idx_hytk_hytk_id_effective
-- ON lq_hytk_hytk(F_Id, F_IsEffective);
-- ============================================
-- 6. lq_hytk_mx (退卡明细表) 索引
-- ============================================
-- 用于:JOIN关联、按会员分组统计
-- 查询条件:F_IsEffective, F_RefundInfoId, F_BillingItemId
-- 索引1:用于JOIN lq_hytk_hytk
CREATE INDEX idx_hytk_mx_refund_effective
ON lq_hytk_mx(F_RefundInfoId, F_IsEffective);
-- 索引2:用于JOIN lq_kd_pxmx
CREATE INDEX idx_hytk_mx_billing_effective
ON lq_hytk_mx(F_BillingItemId, F_IsEffective);
-- ============================================
-- 7. 复合索引(补充优化)
-- ============================================
-- 如果需要进一步优化,可以考虑以下复合索引
-- lq_kd_pxmx: 覆盖查询(包含F_ProjectNumber,避免回表)
-- 注意:此索引较大,请根据数据量决定是否创建
-- CREATE INDEX IF NOT EXISTS idx_kd_pxmx_cover
-- ON lq_kd_pxmx(F_IsEffective, F_MemberId, glkdbh, F_ProjectNumber);
-- lq_xh_pxmx: 覆盖查询(包含F_ProjectNumber)
-- CREATE INDEX IF NOT EXISTS idx_xh_pxmx_cover
-- ON lq_xh_pxmx(F_IsEffective, F_MemberId, F_ConsumeInfoId, F_ProjectNumber);
-- ============================================
-- 索引创建前的检查(避免重复创建)
-- ============================================
-- 执行以下SQL检查索引是否已存在:
-- SELECT
-- TABLE_NAME,
-- INDEX_NAME,
-- GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX) as COLUMNS
-- FROM INFORMATION_SCHEMA.STATISTICS
-- WHERE TABLE_SCHEMA = DATABASE()
-- AND TABLE_NAME IN ('lq_kd_pxmx', 'lq_kd_kdjlb', 'lq_xh_pxmx', 'lq_xh_hyhk', 'lq_hytk_hytk', 'lq_hytk_mx')
-- AND INDEX_NAME LIKE 'idx_%'
-- GROUP BY TABLE_NAME, INDEX_NAME
-- ORDER BY TABLE_NAME, INDEX_NAME;
-- ============================================
-- 索引创建后的验证
-- ============================================
-- 执行以下SQL验证索引是否创建成功:
-- SELECT
-- TABLE_NAME,
-- INDEX_NAME,
-- GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX) as COLUMNS,
-- NON_UNIQUE,
-- CARDINALITY
-- FROM INFORMATION_SCHEMA.STATISTICS
-- WHERE TABLE_SCHEMA = DATABASE()
-- AND TABLE_NAME IN ('lq_kd_pxmx', 'lq_kd_kdjlb', 'lq_xh_pxmx', 'lq_xh_hyhk', 'lq_hytk_hytk', 'lq_hytk_mx')
-- AND INDEX_NAME LIKE 'idx_%'
-- GROUP BY TABLE_NAME, INDEX_NAME, NON_UNIQUE, CARDINALITY
-- ORDER BY TABLE_NAME, INDEX_NAME;
-- ============================================
-- 性能测试建议
-- ============================================
-- 1. 创建索引前,记录查询时间
-- 2. 创建索引后,使用相同参数重新测试
-- 3. 使用 EXPLAIN 分析查询计划,确认索引被使用
-- 4. 如果索引未被使用,检查WHERE条件顺序是否匹配索引列顺序
-- ============================================
-- 注意事项
-- ============================================
-- 1. 索引会占用存储空间,请定期监控
-- 2. 索引会影响INSERT/UPDATE性能,但查询性能提升显著
-- 3. 如果表数据量很大,创建索引可能需要较长时间
-- 4. 建议在业务低峰期执行索引创建
-- 5. MySQL不同版本的兼容性:
-- - MySQL 8.0+ 支持 CREATE INDEX IF NOT EXISTS
-- - MySQL 5.7及以下不支持 IF NOT EXISTS,需要先检查索引是否存在
-- 本文件已移除 IF NOT EXISTS,如索引已存在会报错,可安全忽略
-- 6. 如果报错 "Duplicate key name",说明索引已存在,可以继续执行后面的语句