适合加索引的字段类型包括int、bigint、短varchar/char、datetime/timestamp;text/json需前缀或函数索引;enum/set可索引但语义模糊;全文检索应使用fulltext索引。

哪些 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,还是耗内存。真正卡住性能的,往往不是没建索引,而是建了却没被用上,或者建在了不该建的地方。