哪些 MySQL 字段类型适合加索引?
索引不是给所有字段都加的,关键看查询模式和数据分布。数值型(
INT、
BIGINT)、短字符串(
VARCHAR(16)、
CHAR(10))、时间戳(
DATETIME、
TIMESTAMP)最常被索引——它们比较快、排序稳定、存储紧凑。
TEXT和
JSON类型不能直接建普通 B+ 树索引,必须用前缀(如
content(255))或生成列 + 函数索引(MySQL 5.7+ 支持
JSON_EXTRACT()上建索引)
ENUM和
SET内部存为整数,可以索引,但语义模糊,实际中容易误判范围扫描效果 全文检索需求别硬套 B+ 树,改用
FULLTEXT索引,否则
LIKE '%关键词%'永远走不了索引
WHERE 条件里用了函数,索引还生效吗?
基本不生效。MySQL 在优化器阶段无法将索引值与函数结果对齐,除非你用的是函数索引(MySQL 8.0.13+)或者把函数“下推”到字段定义上。
WHERE YEAR(created_at) = 2024→ 不走
created_at索引
WHERE created_at >= '2024-01-01' AND created_at → 走索引MySQL 8.0 可建函数索引:
CREATE INDEX idx_year ON orders ((YEAR(created_at)))常见陷阱:隐式类型转换,比如
WHERE user_id = '123'(
user_id是
INT),会触发全表扫描而非索引查找
联合索引的字段顺序为什么不能随便调?
B+ 树索引是按字段顺序逐层排序的,等值查询(
=)和最左前缀匹配决定能否使用索引。 索引
(a, b, c)可用于:
WHERE a = 1、
WHERE a = 1 AND b > 10、
WHERE a = 1 AND b = 2 AND c IN (3,4)但
WHERE b = 2或
WHERE c = 3完全用不上这个索引 高频过滤字段放前面;范围查询(
>、
BETWEEN、
LIKE 'abc%')后面的字段索引失效,所以范围字段尽量靠后 排序需求也要纳入考虑:
ORDER BY a, b和
WHERE a = ?匹配
(a,b)索引能避免 filesort
什么时候该删掉已有索引?
索引不是越多越好。每多一个索引,INSERT/UPDATE/DELETE 就多一次 B+ 树维护开销,还占磁盘和内存。
单表索引数超过 5–7 个,就要警惕冗余:用sys.schema_unused_indexes(MySQL 8.0+)或慢日志 +
performance_schema.table_io_waits_summary_by_index_usage查未被使用的索引 重复索引如
(a)和
(a,b),前者通常可删(除非有极轻量查询只查
a) 低选择性字段(如
status ENUM('pending','done','failed'),只有 3 个值)建索引意义很小,优化器大概率会跳过它去走全表扫描
索引设计本质是权衡:查得快,还是写得快;省 IO,还是耗内存。真正卡住性能的,往往不是没建索引,而是建了却没被用上,或者建在了不该建的地方。
