-- 创建普通索引
CREATE INDEX idx_name ON table_name(column_name);
-- 创建唯一索引
CREATE UNIQUE INDEX idx_name ON table_name(column_name);
-- 创建前缀索引(针对文本字段)
CREATE INDEX idx_name ON table_name(column_name(10));
-- 创建多列组合索引
CREATE INDEX idx_name ON table_name(col1, col2, col3);
-- 添加普通索引
ALTER TABLE table_name ADD INDEX idx_name(column_name);
-- 添加唯一索引
ALTER TABLE table_name ADD UNIQUE idx_name(column_name);
-- 添加主键索引
ALTER TABLE table_name ADD PRIMARY KEY(column_name);
-- 添加全文索引(仅MyISAM和InnoDB支持)
ALTER TABLE table_name ADD FULLTEXT idx_name(column_name);
CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- 主键索引
PRIMARY KEY (id),
-- 唯一索引
UNIQUE KEY uk_username (username),
-- 普通索引
KEY idx_email (email),
-- 组合索引
KEY idx_created_email (created_at, email(20)),
-- 全文索引
FULLTEXT idx_content (content)
) ENGINE=InnoDB;
-- 正确的组合索引顺序应考虑查询条件和选择性
CREATE INDEX idx_user_date ON orders(user_id, order_date);
✅ 适合创建索引的列:
❌ 不适合创建索引的列:
-- 最佳实践:遵循最左前缀原则
CREATE INDEX idx_a_b_c ON table(a, b, c);
-- 有效使用索引的查询:
SELECT * FROM table WHERE a = 1;
SELECT * FROM table WHERE a = 1 AND b = 2;
SELECT * FROM table WHERE a = 1 AND b = 2 AND c = 3;
SELECT * FROM table WHERE a = 1 ORDER BY b, c;
-- 无法使用索引的查询:
SELECT * FROM table WHERE b = 2; -- 缺少最左列a
SELECT * FROM table WHERE a = 1 ORDER BY c; -- 跳过了b
-- 1. 对索引列进行运算或函数处理
SELECT * FROM users WHERE YEAR(created_at) = 2023; -- ❌
SELECT * FROM users WHERE created_at >= '2023-01-01'; -- ✅
-- 2. 使用NOT、!=、<>操作符
SELECT * FROM users WHERE status != 'active'; -- ❌
-- 3. 使用OR条件连接(除非所有列都有索引)
SELECT * FROM users WHERE id = 1 OR username = 'john'; -- ❌
-- 4. LIKE以通配符开头
SELECT * FROM users WHERE username LIKE '%john%'; -- ❌
SELECT * FROM users WHERE username LIKE 'john%'; -- ✅
-- 5. 隐式类型转换
SELECT * FROM users WHERE phone = 13800138000; -- ❌ phone是varchar
SELECT * FROM users WHERE phone = '13800138000'; -- ✅
-- 查看表索引
SHOW INDEX FROM table_name;
-- 查看索引使用情况(需要开启性能模式)
EXPLAIN SELECT * FROM users WHERE username = 'john';
-- 删除索引
DROP INDEX idx_name ON table_name;
ALTER TABLE table_name DROP INDEX idx_name;
-- 重建索引(优化索引碎片)
ALTER TABLE table_name ENGINE=InnoDB;
OPTIMIZE TABLE table_name;
-- 查看索引使用统计
SELECT * FROM sys.schema_index_statistics
WHERE table_schema = 'your_database';
-- 查看未使用的索引
SELECT * FROM sys.schema_unused_indexes;
-- 原始表
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
user_id BIGINT,
product_id BIGINT,
status TINYINT,
amount DECIMAL(10,2),
created_at DATETIME
);
-- 优化后的索引策略
CREATE INDEX idx_user_status ON orders(user_id, status);
CREATE INDEX idx_created_user ON orders(created_at, user_id);
CREATE INDEX idx_product_status ON orders(product_id, status);
-- 分区表(针对超大表)
ALTER TABLE orders
PARTITION BY RANGE (YEAR(created_at)) (
PARTITION p2022 VALUES LESS THAN (2023),
PARTITION p2023 VALUES LESS THAN (2024),
PARTITION p2024 VALUES LESS THAN (2025)
);
通过合理使用索引,可以显著提升MySQL查询性能,但需要根据实际业务场景和数据特征进行精心设计和持续优化。