创建一个完整的索引影响查询速度的示例demo,通过实际对比可以直观感受索引的强大作用。
一、测试环境准备
1. 创建测试数据库和表
sql
-- 创建测试数据库
CREATE DATABASE index_demo;
USE index_demo;
-- 创建用户表(无索引状态)
CREATE TABLE users_no_index (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
age INT NOT NULL,
city VARCHAR(50) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 创建用户表(有索引状态)
CREATE TABLE users_with_index (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
age INT NOT NULL,
city VARCHAR(50) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_username (username),
INDEX idx_email (email),
INDEX idx_age_city (age, city),
INDEX idx_created_at (created_at)
);
2. 插入大量测试数据
sql
-- 插入50万条测试数据
DELIMITER $$
CREATE PROCEDURE insert_test_data()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i <= 500000 DO
INSERT INTO users_no_index (username, email, age, city) VALUES (
CONCAT('user', i),
CONCAT('user', i, '@example.com'),
FLOOR(18 + RAND() * 50),
ELT(FLOOR(1 + RAND() * 10), '北京', '上海', '广州', '深圳', '杭州', '南京', '武汉', '成都', '西安', '重庆')
);
INSERT INTO users_with_index (username, email, age, city) VALUES (
CONCAT('user', i),
CONCAT('user', i, '@example.com'),
FLOOR(18 + RAND() * 50),
ELT(FLOOR(1 + RAND() * 10), '北京', '上海', '广州', '深圳', '杭州', '南京', '武汉', '成都', '西安', '重庆')
);
IF i % 10000 = 0 THEN
SELECT CONCAT('已插入 ', i, ' 条数据') AS progress;
END IF;
SET i = i + 1;
END WHILE;
END$$
DELIMITER ;
-- 执行数据插入(这可能需要几分钟)
CALL insert_test_data();
二、性能对比测试
测试1:基本查询对比
sql
mysql> SELECT * FROM users_no_index WHERE username = 'user110000';
+--------+------------+------------------------+-----+--------+---------------------+
| id | username | email | age | city | created_at |
+--------+------------+------------------------+-----+--------+---------------------+
| 110000 | user110000 | user110000@example.com | 36 | 北京 | 2025-12-27 16:33:15 |
+--------+------------+------------------------+-----+--------+---------------------+
1 row in set (0.08 sec)
mysql> SELECT * FROM users_with_index WHERE username = 'user110000';
+--------+------------+------------------------+-----+--------+---------------------+
| id | username | email | age | city | created_at |
+--------+------------+------------------------+-----+--------+---------------------+
| 110000 | user110000 | user110000@example.com | 66 | 成都 | 2025-12-27 16:33:15 |
+--------+------------+------------------------+-----+--------+---------------------+
1 row in set (0.00 sec)
测试2:精确的性能测量
sql
mysql> SET profiling = 1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql>
mysql> SELECT * FROM users_no_index WHERE username = 'user110000';
+--------+------------+------------------------+-----+--------+---------------------+
| id | username | email | age | city | created_at |
+--------+------------+------------------------+-----+--------+---------------------+
| 110000 | user110000 | user110000@example.com | 36 | 北京 | 2025-12-27 16:33:15 |
+--------+------------+------------------------+-----+--------+---------------------+
1 row in set (0.07 sec)
mysql> SHOW PROFILE FOR QUERY 1;
+--------------------------------+----------+
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000094 |
| Executing hook on transaction | 0.000006 |
| starting | 0.000034 |
| checking permissions | 0.000006 |
| Opening tables | 0.000034 |
| init | 0.000011 |
| System lock | 0.000007 |
| optimizing | 0.000011 |
| statistics | 0.000022 |
| preparing | 0.000021 |
| executing | 0.073159 |
| end | 0.000040 |
| query end | 0.000004 |
| waiting for handler commit | 0.000007 |
| closing tables | 0.000008 |
| freeing items | 0.000220 |
| cleaning up | 0.000018 |
+--------------------------------+----------+
17 rows in set, 1 warning (0.00 sec)
mysql> SELECT * FROM users_with_index WHERE username = 'user110000';
+--------+------------+------------------------+-----+--------+---------------------+
| id | username | email | age | city | created_at |
+--------+------------+------------------------+-----+--------+---------------------+
| 110000 | user110000 | user110000@example.com | 66 | 成都 | 2025-12-27 16:33:15 |
+--------+------------+------------------------+-----+--------+---------------------+
1 row in set (0.00 sec)
mysql>
mysql> SHOW PROFILE FOR QUERY 2;
+--------------------------------+----------+
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000096 |
| Executing hook on transaction | 0.000006 |
| starting | 0.000005 |
| checking permissions | 0.000005 |
| Opening tables | 0.000040 |
| init | 0.000005 |
| System lock | 0.000006 |
| optimizing | 0.000011 |
| statistics | 0.000089 |
| preparing | 0.000040 |
| executing | 0.000051 |
| end | 0.000005 |
| query end | 0.000005 |
| waiting for handler commit | 0.000007 |
| closing tables | 0.000006 |
| freeing items | 0.000168 |
| cleaning up | 0.000012 |
+--------------------------------+----------+
17 rows in set, 1 warning (0.00 sec)
mysql> SHOW PROFILES;
+----------+------------+--------------------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+--------------------------------------------------------------+
| 1 | 0.07369975 | SELECT * FROM users_no_index WHERE username = 'user110000' |
| 2 | 0.00055400 | SELECT * FROM users_with_index WHERE username = 'user110000' |
+----------+------------+--------------------------------------------------------------+
2 rows in set, 1 warning (0.00 sec)