MySQL中如何为SELECT语句实现类似LOW_PRIORITY的效果?
实现类似LOW_PRIORITY的慢LIKE查询资源控制方案
利用MySQL资源组(Resource Groups)
MySQL 8.0及以上版本支持资源组功能,可创建低优先级资源组,将这类慢查询的线程分配到该组,限制其CPU使用率和线程优先级:- 创建低优先级资源组:
CREATE RESOURCE GROUP low_priority_group TYPE = USER VCPU = 0-1 -- 根据服务器CPU核心数调整,限制使用特定核心 THREAD_PRIORITY = -10; -- 值越小优先级越低,范围-20到19 - 执行慢查询前切换资源组:
SET RESOURCE GROUP low_priority_group; SELECT * FROM user WHERE phone LIKE '%xxxx%'; -- 查询完成后切回默认组 SET RESOURCE GROUP default;
注意:需开启
performance_schema,且操作用户需拥有RESOURCE_GROUP_ADMIN权限。- 创建低优先级资源组:
设置查询执行时间限制
通过会话变量或查询提示限制慢查询的最大执行时间,避免长时间占用CPU:- 会话级配置:
SET SESSION max_execution_time = 5000; -- 单位毫秒,即5秒 SELECT * FROM user WHERE phone LIKE '%xxxx%'; - 查询级提示(MySQL 5.7.8+支持):
SELECT /*+ MAX_EXECUTION_TIME(5000) */ * FROM user WHERE phone LIKE '%xxxx%';
当查询超时后,MySQL会自动终止该请求,防止持续消耗资源。
- 会话级配置:
操作系统层面调整线程优先级
通过系统工具降低慢查询线程的优先级,让系统优先分配CPU给其他请求:- 用
SHOW PROCESSLIST找到目标查询的线程ID。 - Linux系统下用
renice调整优先级:renice 10 -p <线程ID>
数值越大(范围-20到19),线程优先级越低,获取CPU资源的优先级也越低。
- 用
预处理数据优化查询(根源解决)
如果业务允许,可提前提取手机号中间四位为单独字段并建立索引,替代全表扫描的LIKE查询:- 添加字段并更新数据:
ALTER TABLE user ADD COLUMN phone_middle_4 VARCHAR(4); UPDATE user SET phone_middle_4 = SUBSTRING(phone, 4, 4); -- 适配11位手机号的中间四位提取逻辑 - 建立索引:
CREATE INDEX idx_phone_middle_4 ON user(phone_middle_4); - 优化后查询:
SELECT * FROM user WHERE phone_middle_4 = 'xxxx';
这种方法可彻底消除全表扫描带来的CPU高负载问题,是最优解决方案。
- 添加字段并更新数据:
内容的提问来源于stack exchange,提问作者Qiulang
相关产品推荐
相关产品推荐

