类比理解:索引就像书的目录。比如你想查《哈利波特》中 “伏地魔” 出现的页数,不用逐页翻书,直接看目录找关键词就行。数据库里的索引就是帮你快速找到数据的 “目录”。
适用场景:90% 的场景都能用,比如:
1 |
CREATE INDEX idx_age ON users(age); -- 给年龄字段建索引 |
1 |
CREATE FULLTEXT INDEX idx_article ON articles(content); |
1 |
CREATE INDEX idx_name_age ON users(name, age); |
1 2 |
WHERE name='张三' AND age=18; -- 正确,用全索引 WHERE name='张三'; -- 正确,用name部分 |
不支持:
1 2 |
WHERE age=18; -- 错误,跳过了name,索引失效 WHERE name='张三' AND age=18 AND address='北京'; -- 正确,address不影响,前两个字段用上索引 |
1 2 3 |
-- 表结构:users(id, name, age) CREATE INDEX idx_name_age ON users(name, age); -- 索引包含name和age SELECT name, age FROM users WHERE name='张三'; -- 直接从索引取数据,不用回表 |
1 |
WHERE UPPER(name)='ZHANGSAN'; -- 对name做了大写转换,索引失效 |
类型不匹配:
1 |
WHERE id='123'; -- id是数字类型,传字符串可能导致索引失效 |
模糊查询以通配符开头:
1 |
WHERE name LIKE '%张三'; -- 无法用索引(不知道从哪开始查) |
OR 条件分隔无关联字段:
1 |
WHERE id=1 OR name='张三'; -- 若id和name没有共同索引,可能失效 |
创建索引:
1 2 |
CREATE INDEX idx_name ON users(name); -- 普通索引 CREATE UNIQUE INDEX idx_email ON users(email); -- 唯一索引 |
删除索引:
1 |
DROP INDEX idx_name ON users; |
查看索引:
1 |
SHOW INDEX FROM users; |
分析查询是否用索引:
1 |
EXPLAIN SELECT * FROM users WHERE name='张三'; -- 看执行计划中的Key列 |
引擎 | 支持的索引类型 | 特点 |
---|---|---|
InnoDB | BTree、全文、空间 | 数据和索引存一起(聚簇索引),适合事务 |
MyISAM | BTree、全文、RTree | 索引和数据分开存,不支持事务 |
Memory | Hash、BTree | 数据在内存,查询极快,但重启数据丢失 |
查询 “近 30 天内,已支付(status=2)且金额> 1000 的订单”,按时间倒序。
1 2 3 4 5 6 7 |
CREATE TABLE orders ( id BIGINT PRIMARY KEY, user_id BIGINT, order_time DATETIME, status TINYINT, amount DECIMAL(10,2) ); |
创建联合覆盖索引:
1 |
CREATE INDEX idx_status_time_amount ON orders(status, order_time, amount); |
查询语句:
1 2 3 |
SELECT id, user_id, amount FROM orders WHERE status=2 AND order_time >= NOW() - INTERVAL 30 DAY AND amount > 1000 ORDER BY order_time DESC; |
通过合理设计索引,MySQL 查询性能能提升 10-100 倍!但记住:索引不是越多越好,要在 “查询速度” 和 “写入速度” 之间找平衡哦~