首页 >> 基础教程

慢SQL的优化方法

       MySQL 数据库的 SQL 优化是提升性能的核心环节,主要从 减少数据扫描量降低计算复杂度 和 避免资源竞争 三大方向切入。以下是具体优化方向及实践策略:

一、索引优化(核心方向)

  1. 精准添加索引

    1. WHERE/JOIN/ORDER BY/GROUP BY 高频过滤列必建索引

    2. 联合索引遵循最左前缀原则((a,b,c) 可支持 a | a,b | a,b,c 查询)

    3. 覆盖索引:避免回表(SELECT 字段全部在索引中

  2. 避免索引失效场景

    1. 禁止对索引列 函数操作WHERE YEAR(create_time)=2023 换成WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31' 

    2. 避免隐式类型转换:WHERE phone=13800138000(若 phone 是字符串类型则失效)

    3. LIKE 左模糊禁止:LIKE '%abc'换成LIKE 'abc%' 

二、SQL 语句重写优化

  1. 避免全表扫描

    1. 禁用 SELECT *,只取必要字段

    2. 分页深度优化:用 游标分页 替代 OFFSET

    -- 传统分页(越后越慢)
    SELECT * FROM orders ORDER BY id LIMIT 100000, 20;
    
    -- 游标分页(恒定速度)
    SELECT * FROM orders WHERE id > 100000 ORDER BY id LIMIT 20;
  2. 子查询优化

    1. 关联子查询 → JOIN:减少嵌套查询次数

      1. -- 低效:逐行执行子查询
        SELECT * FROM users u 
        WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);
        -- 高效:JOIN 一次完成
        SELECT DISTINCT u.* FROM users u 
        JOIN orders o ON u.id = o.user_id;
    2. join查询注意驱动表,提前筛选出要查询的数据量

  3. 避免临时表与文件排序

    1. ORDER BY/GROUP BY 字段与索引顺序一致

    2. 大结果集分阶段处理(如分批聚合)

三、执行计划深度调优

  1. 强制索引选择

    1. 当优化器选错索引时,用 FORCE INDEX 干预

  2. 拆解复杂 SQL

    1. 多表 JOIN 拆分为单表查询 + 程序内存计算

    2. 大批量更新分批次执行(减少锁竞争)

      1. -- 单次更新100万行 → 锁表风险
        UPDATE logs SET status=1 WHERE create_time < '2023-01-01';
        -- 分批更新(每批1万行)
        WHILE (affected_rows > 0) DO
          UPDATE logs SET status=1 
          WHERE create_time < '2023-01-01' 
          LIMIT 10000;
        END WHILE;

四、数据类型与表达式优化

  1. 类型精确匹配

    • 避免字符串与数字比较:WHERE id = '100' → WHERE id = 100

    • 枚举值使用 ENUM 类型(减少存储+加速过滤)

  2. 短路计算应用

    • 高过滤性条件前置:

      • -- 优先用 status 过滤(假设status过滤90%数据)
        SELECT * FROM orders 
        WHERE status = 'shipped' AND total_price < 100;

五、高级策略与架构协同

  1. 读写分离

    • 报表类查询路由到只读副本,减轻主库压力

  2. 缓存层拦截

    • 热点数据(如商品信息)用 Redis 缓存,避免重复查询

  3. 异步处理

    • 非实时统计任务写入消息队列(如 Kafka)异步计算



最新文章
mysql分页问题2025-08-04
千万数据先insert和先建索引哪个快2025-08-04
MySQL 中大小表关联查询如何优化2025-08-04
sql技巧-每个班年龄排前两名的人2025-08-03
MySQL 导致 cpu 飙升的话,要怎么处理呢?2025-07-29
MySQL 中为千万级大表添加字段2025-07-29
mysql中百万级别以上的数据如何删除2025-07-29
分库分表带来的问题2025-07-29
mysql中常用的分库分表中间件有哪些2025-07-29
mysql不停机扩容2025-07-29
备案号:蜀ICP备2023042032号-1