MySQL 查询慢?项目接口性能优化全攻略(附方案对比)

529 阅读2分钟

随着项目数据量的增长,接口响应慢、查询卡顿、数据库压力飙升成为常见问题。本文将结合实际项目,从多个角度(数据库设计、查询优化、缓存策略、搜索引擎、分库分表)出发,详解如何优化查询性能。

✅ 优化目标

  • 降低查询响应时间
  • 减轻数据库压力
  • 提升系统稳定性和可扩展性

🧱 一、MySQL 查询层优化

1. 添加合适索引

  • 针对 WHEREORDER BYJOIN 字段建立联合索引
  • 避免在索引字段使用函数或不等号(如 !=, <>

示例:

-- 不推荐:函数使索引失效
SELECT * FROM users WHERE DATE(created_at) = '2024-01-01';

-- 推荐写法:
SELECT * FROM users WHERE created_at >= '2024-01-01' AND created_at < '2024-01-02';

2. 分页优化

-- 慢分页
SELECT * FROM orders ORDER BY id LIMIT 100000, 10;

-- 快分页
SELECT * FROM orders WHERE id > 100000 ORDER BY id LIMIT 10;

3. SQL 查询重写

  • 避免 SELECT *
  • 拆解复杂 JOIN 查询为多次小查询 + 内存拼接

🚀 二、引入缓存层

使用场景

  • 高频访问、数据变动不频繁
  • 详情页、列表页、配置信息等

常见缓存方案

缓存类型场景推荐工具
本地缓存单机、热点数据Caffeine、Guava
分布式缓存多节点共享Redis、Memcached

示例架构:

public User getUserDetail(Long id) {
    User user = redis.get("user:" + id);
    if (user != null) return user;

    user = db.queryById(id);
    redis.set("user:" + id, user, 10min);
    return user;
}

🔎 三、复杂查询交给 Elasticsearch

示例场景

  • 商品搜索
  • 博客模糊匹配
  • 用户行为分析

示例对比:

-- MySQL 查询:
SELECT * FROM article WHERE title LIKE '%mysql%' AND tag='数据库';
-- ES DSL 查询:
{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "mysql" } },
        { "term": { "tag": "数据库" } }
      ]
    }
  }
}

🏗️ 四、分库分表应对大数据量

常见方案:

类型特点工具
水平分表按业务主键分片ShardingSphere, MyCat
垂直拆库按模块拆表至多个库手动拆库、微服务

示例:使用 Sharding-JDBC 分片

tables:
  user:
    actualDataNodes: ds${0..1}.user_${0..15}
    tableStrategy:
      inline:
        shardingColumn: user_id
        algorithmExpression: user_${user_id % 16}

🧠 五、异步化处理非核心查询

  • 使用消息队列投递
  • 后台批处理更新缓存
  • 用队列防抖聚合更新

✅ 最佳实践组合推荐

场景推荐优化组合
用户详情页Redis 缓存 + ID 索引优化
搜索接口Elasticsearch + 缓存
大列表分页游标分页 + 分表
报表查询MySQL 预计算 + 缓存 + 异步更新
订单系统分库分表 + 缓存热点订单

📌 总结

接口慢不是“数据库背锅”,而是系统全链路的问题。
需要数据库优化 + 缓存加速 + 搜索引擎 + 分布式架构的组合拳。

查询慢 ≠ SQL 慢,更多时候是整体架构设计不合理。