四时宝库

程序员的知识宝库

MySQL索引优化10大法则:百万级查询秒变毫秒响应!

数据库性能优化的核心在于索引的合理使用。本文将通过10个黄金法则,结合真实场景案例,揭示如何让百万级数据查询效率提升百倍的实战技巧。


一、索引优化十大黄金法则

1. 精准索引法则

选择区分度>30%的字段创建索引,避免对性别等低区分度字段建索引

-- 错误示范
CREATE INDEX idx_gender ON users(gender);

-- 正确做法
CREATE INDEX idx_mobile ON users(mobile);

2. 最左匹配原则

联合索引(a,b,c)生效场景:

  • WHERE a=1 AND b=2 AND c=3
  • WHERE a=1 AND b>2
  • WHERE a=1 ORDER BY b

失效场景:

  • WHERE b=2 AND c=3
  • WHERE a>1 AND b=2

3. 覆盖索引优先

当索引包含所有查询字段时,性能提升3-10倍

-- 需要回表
SELECT * FROM orders WHERE user_id=100;

-- 覆盖索引
CREATE INDEX idx_user_status ON orders(user_id, status);
SELECT user_id, status FROM orders WHERE user_id=100;

4. 函数失效陷阱

索引列参与计算或函数时索引失效

-- 索引失效
SELECT * FROM logs WHERE YEAR(create_time)=2023;

-- 优化方案
SELECT * FROM logs 
WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31';

5. 前缀索引技巧

对长文本字段使用前缀索引,节省70%存储空间

CREATE INDEX idx_comment_prefix ON comments(comment(20));

6. 排序优化策略

ORDER BY字段与索引顺序一致可避免filesort

-- 需要filesort
CREATE INDEX idx_age ON users(age);
SELECT * FROM users ORDER BY age DESC, name ASC;

-- 优化索引
CREATE INDEX idx_age_name ON users(age DESC, name ASC);

7. 索引下推(ICP)

MySQL5.6+自动启用,减少回表次数达90%

SET optimizer_switch='index_condition_pushdown=on';

8. 索引合并优化

合理利用index_merge提升OR条件查询效率

EXPLAIN SELECT * FROM products 
WHERE category_id=5 OR price>1000;

9. 死锁预防方案

更新操作按固定顺序执行,避免间隙锁冲突

-- 危险操作
UPDATE account SET balance=balance-100 WHERE id=1;
UPDATE account SET balance=balance+100 WHERE id=2;

-- 安全方案
BEGIN;
SELECT * FROM account WHERE id IN (1,2) FOR UPDATE;
UPDATE account SET balance=... WHERE id=1;
UPDATE account SET balance=... WHERE id=2;
COMMIT;

10. 索引监控体系

定期分析索引使用率,清理冗余索引

SELECT * FROM sys.schema_unused_indexes;
SELECT * FROM sys.schema_redundant_indexes;

二、千万级数据优化实战

案例背景

电商订单表(order)含1200万数据,查询最近3个月某用户的待发货订单耗时8.2秒

原始表结构

CREATE TABLE orders (
  id BIGINT PRIMARY KEY,
  user_id INT,
  status TINYINT,
  amount DECIMAL(10,2),
  create_time DATETIME
);

慢查询语句

SELECT * FROM orders 
WHERE user_id=12345 
  AND status=1 
  AND create_time >= DATE_SUB(NOW(), INTERVAL 3 MONTH)
ORDER BY create_time DESC
LIMIT 10;

优化四部曲

  1. 执行计划分析
EXPLAIN SELECT... -- 显示全表扫描
  1. 索引重构方案
ALTER TABLE orders ADD INDEX idx_user_status_time
(user_id, status, create_time DESC);
  1. 查询改写优化
SELECT * FROM orders 
FORCE INDEX(idx_user_status_time)
WHERE user_id=12345 
  AND status=1 
  AND create_time >= '2023-03-01'
ORDER BY create_time DESC 
LIMIT 10;
  1. 效果验证
  • 扫描行数:从1200万 → 35行
  • 执行时间:8200ms → 8ms
  • 磁盘IO:从物理读 → 内存读

三、索引维护最佳实践

  1. 碎片整理周期
ALTER TABLE orders ENGINE=InnoDB; -- 每月执行
ANALYZE TABLE orders; -- 每周更新统计信息
  1. 热数据预加载
SELECT SQL_CACHE * FROM hot_products WHERE id IN (...);
  1. 读写分离架构
# 配置MySQL组复制
group_replication_group_seeds = "node1:3306,node2:3306,node3:3306"

四、性能对比数据

优化阶段

数据量

查询耗时

扫描方式

无索引

1200万

8200ms

全表扫描

单列索引

1200万

450ms

索引扫描

联合索引

1200万

8ms

覆盖索引

缓存命中

热点数据

0.5ms

内存直接访问


结语: 索引优化是持续迭代的过程,需要结合EXPLAIN分析、慢查询日志和性能监控工具,建立从索引设计到维护的完整体系。通过本文的10大法则,可使90%的慢查询问题得到显著改善。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接