1. MySQL索引优化实战:从原理到落地的深度解析
作为一名长期奋战在数据库优化一线的工程师,我深知索引优化对系统性能的关键影响。今天我将基于InnoDB存储引擎的B+Tree索引特性,结合10万级测试数据,带大家深入MySQL索引优化的核心战场。这不是一篇泛泛而谈的理论文章,而是凝结了我多年实战经验的深度指南,包含大量你在官方文档中找不到的实操技巧和避坑经验。
1.1 环境准备与测试数据构建
在开始优化前,我们需要一个标准的测试环境。以下是创建测试表的SQL语句,这张employees表将成为我们所有实验的基础:
sql复制CREATE TABLE `employees` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(24) NOT NULL DEFAULT '',
`age` int(11) NOT NULL DEFAULT '0',
`position` varchar(20) NOT NULL DEFAULT '',
`hire_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_name_age_position` (`name`,`age`,`position`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 插入10万条测试数据的存储过程
DELIMITER ;;
CREATE PROCEDURE insert_emp()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE(i<=100000)DO
INSERT INTO employees(name,age,position) VALUES(CONCAT('xiaoming',i),i,'dev');
SET i=i+1;
END WHILE;
END;;
DELIMITER ;
CALL insert_emp();
这个表结构有几个关键设计点:
- 主键采用自增ID,这是InnoDB表的标准做法
- 建立了联合索引idx_name_age_position(name,age,position)
- 使用存储过程批量插入10万条测试数据,确保数据量足够大以观察索引效果
注意:在实际生产环境,建议使用更真实的数据分布,而不是简单的连续数据。可以使用RAND()函数生成更接近真实场景的数据分布。
2. 联合索引实战:五大核心场景深度解析
2.1 场景一:联合索引首字段范围查询的陷阱
让我们从一个典型的范围查询开始:
sql复制EXPLAIN SELECT * FROM employees WHERE name > 'LiLei' AND age = 22 AND position ='manager';
执行计划显示:
- type=ALL(全表扫描)
- key=NULL(未使用索引)
- Extra=Using where(在服务层过滤)
底层原理:MySQL优化器通过成本计算判定,当首字段使用范围查询时,即使后续字段在索引中,也需要对大量记录进行回表操作。二级索引扫描+回表的总IO成本可能高于直接全表扫描。
实战技巧:
- 对于必须使用范围查询的场景,考虑使用覆盖索引优化:
sql复制EXPLAIN SELECT name,age,position FROM employees WHERE name > 'LiLei' AND age = 22 AND position ='manager';
`
