1. MySQL优化全攻略从索引设计到分库分表的实战手册刚入行时接手过一个日活百万的社区项目数据库查询经常超过3秒。有次凌晨三点被报警叫醒处理慢查询才发现原来只是漏加了一个联合索引。这种血泪教训让我意识到MySQL优化不是高端技巧而是每个开发者必须掌握的生存技能。本文将分享我十年踩坑总结的优化体系涵盖索引设计、SQL调优、分库分表三大核心模块所有案例均来自真实生产环境。2. 索引优化从B树原理到避坑指南2.1 索引底层结构与选择策略MySQL的InnoDB引擎采用B树索引结构其特点是非叶子节点只存键值和指针单个节点可存储更多索引项叶子节点形成双向链表支持高效范围查询数据记录存放在叶子节点聚簇索引直接包含完整数据实测对比1000万数据量查询类型无索引耗时有索引耗时主键等值查询2.8s0.003s范围查询(age20)4.1s0.12s模糊查询(like%)3.9s3.7s关键结论索引对等值查询和范围查询效果显著但无法优化左模糊查询2.2 复合索引设计黄金法则设计复合索引时我遵循三星索引原则第一星WHERE条件列作为前导列第二星ORDER BY列加入索引第三星SELECT字段被索引覆盖实际案例用户中心查询场景-- 高频查询 SELECT user_id, username FROM users WHERE city北京 AND age25 ORDER BY create_time DESC最优索引方案ALTER TABLE users ADD INDEX idx_city_age_ctime(city, age, create_time);2.3 索引失效的八大陷阱隐式类型转换字段定义为varchar但用数字查询-- user_id是varchar类型 SELECT * FROM users WHERE user_id 10086; -- 失效函数操作对索引列使用函数SELECT * FROM orders WHERE DATE(create_time)2023-01-01;前导模糊匹配like以通配符开头SELECT * FROM products WHERE name LIKE %手机%;OR条件未全覆盖OR两侧条件未全部索引-- 只有name有索引 SELECT * FROM users WHERE name张三 OR age20;!或操作负向条件查询SELECT * FROM orders WHERE status ! paid;索引列运算对列进行数学运算SELECT * FROM products WHERE price*2 100;最左前缀缺失复合索引跳过前导列-- 有索引idx_a_b_c SELECT * FROM table WHERE b1 AND c2;范围查询阻断复合索引中范围查询后的列失效-- idx_city_age_name索引中name无法使用 SELECT * FROM users WHERE city北京 AND age20 AND name张三;3. SQL语句优化实战技巧3.1 执行计划深度解读使用EXPLAIN时重点关注type列从优到差 system const eq_ref ref range index ALLkey_len实际使用的索引长度可判断是否用到全部索引列Extra列Using index覆盖索引Using filesort需要额外排序Using temporary使用临时表典型问题诊断案例EXPLAIN SELECT * FROM orders o JOIN users u ON o.user_idu.id WHERE o.create_time2023-01-01 ORDER BY u.username;优化方案为orders表添加(user_id, create_time)复合索引为users表username字段添加索引修改查询只返回必要字段3.2 连接查询优化策略JOIN执行原理Nested Loop Join适合小表驱动大表Hash JoinMySQL 8.0支持等值连接高效Sort-Merge Join大数据量且已排序场景优化建议控制JOIN表数量不超过3张确保关联字段有索引大表JOIN使用子查询先过滤SELECT * FROM big_table JOIN (SELECT id FROM small_table WHERE ...) filtered ON big_table.id filtered.id3.3 分页查询优化方案典型问题查询SELECT * FROM orders ORDER BY id LIMIT 1000000, 10;优化方案对比方案原理适用场景延迟关联先查主键再回表通用方案书签记录记录上次查询位置顺序分页预生成分页表定时任务提前计算高实时性要求低延迟关联实现SELECT * FROM orders o JOIN (SELECT id FROM orders ORDER BY id LIMIT 1000000, 10) tmp ON o.id tmp.id;4. 分库分表架构设计与实践4.1 拆分策略选型指南垂直拆分按业务模块拆分用户库、订单库、商品库优点业务解耦便于扩展缺点无法解决单表数据量过大问题水平拆分按分片键分散数据用户ID哈希、时间范围常用分片算法哈希取模分片序号 user_id % 分片数范围分片按时间或ID区间划分一致性哈希减少扩容数据迁移量选型建议先垂直后水平单表超500万行考虑水平拆分4.2 ShardingSphere实战配置核心配置示例YAML格式spring: shardingsphere: datasource: names: ds0,ds1 ds0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.jdbc.Driver jdbc-url: jdbc:mysql://db0:3306/order_db username: root password: 123456 ds1: # 类似配置... sharding: tables: t_order: actual-data-nodes: ds$-{0..1}.t_order_$-{0..15} table-strategy: inline: sharding-column: order_id algorithm-expression: t_order_$-{order_id % 16} database-strategy: inline: sharding-column: user_id algorithm-expression: ds$-{user_id % 2}4.3 分库分表后的挑战与解决方案分布式ID生成雪花算法Snowflake64位ID 时间戳(41) 机器ID(10) 序列号(12)美团Leaf号段模式双Buffer优化数据库自增序列需中心化服务跨分片查询字段冗余将常用查询字段冗余到各分片异构索引表建立专门的查询索引表最终一致性通过消息队列同步数据事务处理XA协议两阶段提交性能较差TCC模式Try-Confirm-Cancel需业务改造SAGA模式长事务拆分为子事务补偿机制5. 性能监控与持续优化5.1 关键监控指标指标类别监控项告警阈值连接池活跃连接数 最大连接数80%查询性能慢查询率 1%资源使用CPU利用率 70%持续5分钟复制延迟主从延迟秒数 30秒5.2 性能分析工具链实时诊断SHOW PROCESSLIST查看当前会话SHOW ENGINE INNODB STATUSInnoDB状态详情历史分析慢查询日志需开启log_queries_not_using_indexesPerformance Schema记录详细执行统计可视化工具Prometheus Grafana指标监控看板pt-query-digest慢查询分析工具5.3 参数调优模板典型my.cnf配置16核64GB内存服务器[mysqld] # 内存配置 innodb_buffer_pool_size 48G # 物理内存的70%-80% key_buffer_size 512M query_cache_size 0 # MySQL8已移除 # 连接配置 max_connections 1000 thread_cache_size 100 table_open_cache 4000 # InnoDB配置 innodb_flush_log_at_trx_commit 2 # 非金融业务可牺牲部分持久性 innodb_log_file_size 2G innodb_io_capacity 2000 # SSD建议值6. 真实案例电商系统优化实录某电商平台大促期间出现数据库CPU持续100%的问题通过以下步骤解决问题定位使用pt-query-digest分析慢查询日志发现商品搜索接口平均响应2.3秒SQL优化-- 原查询执行时间2.1s SELECT * FROM products WHERE category_id5 AND status1 ORDER BY sales_volume DESC LIMIT 100; -- 优化后0.03s SELECT p.* FROM products p JOIN (SELECT id FROM products WHERE category_id5 AND status1 ORDER BY sales_volume DESC LIMIT 100) tmp ON p.idtmp.id;架构升级引入Elasticsearch处理商品搜索对订单表按用户ID哈希分16个库使用Redis缓存热点商品数据优化效果数据库QPS从1500提升到4200平均响应时间从1.2s降至0.15s大促期间零宕机