请求优化指定MySQL查询语句(附目标SQL代码)
MySQL查询性能优化方案
优化后的查询语句
SELECT EXISTS( SELECT 1 FROM usergroups item_t1 WHERE item_t1.p_uid = item_t0.p_b2bunits AND item_t1.TypePkString = 8796095217746 ) AS active, item_t0.p_b2bunits AS code, item_t0.p_accountname AS name1, item_t0.p_accountnameextension AS name2, EXISTS( SELECT 1 FROM user2salreprelation item_t2 WHERE item_t2.SourcePK = item_t0.PK AND item_t2.TargetPK = 8828959653892 AND item_t2.TypePkString = 8796150399058 ) AS isFav FROM account2salesrep item_t0 WHERE item_t0.TypePkString = 8796149842002 AND item_t0.p_showondashboard = 1 AND item_t0.p_district = '4' AND ( item_t0.p_accountname LIKE '%crampel alu%' OR item_t0.p_accountnameextension LIKE '%crampel alu%' OR item_t0.p_b2bunits LIKE '%crampel alu%' ) ORDER BY item_t0.p_accountname LIMIT 0, 11;
具体优化措施
1. 简化表达式,减少冗余计算
- 去掉
CASE WHEN包装:EXISTS本身返回布尔值,可直接赋值给字段,无需额外判断THEN true ELSE false,降低计算开销。 - 简化模糊查询拼接:将多层
CONCAT直接改为'%crampel alu%',避免不必要的字符串运算。 - 移除冗余
LOWER():若数据库排序规则为不区分大小写(如utf8mb4_general_ci),LIKE会自动忽略大小写,保留LOWER()会导致索引失效。
2. 创建针对性索引,消除全表扫描
主表account2salesrep索引
创建覆盖过滤、排序和查询列的复合索引,避免回表:
CREATE INDEX idx_account2salesrep_core ON account2salesrep ( TypePkString, p_showondashboard, p_district, p_accountname ) INCLUDE (p_b2bunits, p_accountnameextension, PK);
- 把过滤性强的字段放在索引最前列,快速缩小数据范围。
- 包含排序字段
p_accountname,利用索引完成排序,避免文件排序。 - 用
INCLUDE(MySQL 8.0+支持)包含查询所需字段,实现索引覆盖。
关联表usergroups索引
匹配子查询条件的复合索引:
CREATE INDEX idx_usergroups_uid_type ON usergroups (p_uid, TypePkString);
关联表user2salreprelation索引
覆盖子查询多条件的复合索引:
CREATE INDEX idx_user2salreprelation_source_target_type ON user2salreprelation (SourcePK, TargetPK, TypePkString);
3. 额外优化建议
- 若模糊查询为高频场景,可考虑用全文索引替代
%xxx%类型的模糊查询(此类模糊查询无法利用普通字段索引)。 - 检查
p_district字段类型:如果是数字类型,将过滤条件的'4'改为4,避免类型转换导致索引失效。 - 定期更新表统计信息,帮助优化器生成最优执行计划:
ANALYZE TABLE account2salesrep, usergroups, user2salreprelation;
内容的提问来源于stack exchange,提问作者sunil sharma
相关产品推荐
相关产品推荐

