MySQL索引选择与数据类型优化建议
MySQL中如何选择合适的索引列?数据类型选择有哪些优化建议?请从索引选择性(区分度)、字段长度、前缀索引、覆盖索引等方面展开说明。
回答
我还是少年
索引列选择原则:
-
高选择性(高区分度)列:
- 选择性 = DISTINCT值数 / 总行数,越接近1越好
- 如:性别(选择性低,只有2种)不适合单独建索引
- 身份证号(近乎唯一)适合建索引
-
WHERE条件频率高的列优先建索引
-
ORDER BY和GROUP BY涉及的列
-
JOIN关联列:优化联表查询
-
最左前缀:联合索引将选择性高的列放在最前面
前缀索引:
-- 对长字符串列(如varchar(200))只索引前N个字符
CREATE INDEX idx_email_prefix ON user(email(10));
数据类型优化:
-
选择最小数据类型:
- 能用TINYINT不用SMALLINT(如年龄使用TINYINT UNSIGNED)
- 能用INT不用BIGINT(如果值范围满足)
-
使用UNSIGNED(非负值时)
-
优先使用整数类型替代字符串:
- 存储IP使用INT(INET_ATON/INET_NTOA转换)
- 存储状态使用TINYINT枚举(而非VARCHAR)
-
VARCHAR vs CHAR:
- 变长用VARCHAR(节省空间)
- 定长用CHAR(如MD5值CHAR(32))
- VARCHAR长度合理设置(过大会浪费内存排序)
-
自增主键 vs UUID主键:
- 自增INT/BIGINT主键(顺序写入,页分裂少,B+Tree更紧凑)
- UUID主键(随机写入,频繁页分裂,索引效率低)
-
日期类型:
- 用DATE/DATETIME/TIMESTAMP不用VARCHAR存
- TIMESTAMP占用4字节,DATETIME占用5-8字节(5.6.4+)