java应用连接mysql时,索引由mysql管理,开发者需在建表或上线前设计索引策略;主键索引必须且唯一,默认聚簇索引;唯一索引允许多个、可含null;普通索引需遵循最左前缀原则并避免低区分度字段。

Java 应用连接 MySQL 时,索引不是 Java 写的,而是由 MySQL 数据库本身管理的——但 Java 开发者必须在建表、改表或上线前主动设计好索引策略,否则查询慢、CPU 高、连接超时等问题会直接反映在应用层。核心不是“怎么写 Java 代码加索引”,而是“怎么结合业务 SQL,在 MySQL 里正确建索引”,Java 端只需确保执行 DDL 或调用框架(如 Flyway、MyBatis-Plus)下发这些语句即可。
主键索引:每张表必须有,且只能有一个
主键索引是默认聚簇索引(InnoDB),决定了数据物理存储顺序,对范围查询、ORDER BY 和 JOIN 效果显著。它自动具备唯一性+非空约束,无需额外声明 UNIQUE 或 NOT NULL。
- 建表时定义最稳妥:
CREATE TABLE user (id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50)) - 已有表补主键需确保列值唯一且无 NULL:
ALTER TABLE user ADD PRIMARY KEY (id) - 避免用 UUID 或字符串做主键——长、无序、导致页分裂,优先选自增数字或雪花 ID(注意 Java 生成后插入时需显式指定)
唯一索引:用于业务上要求不重复的关键字段
比如手机号、邮箱、订单号。它和主键索引一样保证唯一性,但允许 NULL,且一张表可建多个。
- 建表时加:
email VARCHAR(100) UNIQUE - 单独创建:
CREATE UNIQUE INDEX uk_user_email ON user(email) - 复合唯一索引适合多字段组合唯一场景,例如「用户+商品」不能重复收藏:
CREATE UNIQUE INDEX uk_user_item ON favorite(user_id, item_id) - 注意 NULL 不参与唯一校验——同一列多个 NULL 值不会冲突
普通索引:加速 WHERE、JOIN、ORDER BY 的主力
这是最常用也最容易滥用的索引类型。关键不是“有没有”,而是“建在哪、怎么建”。MySQL 优化器是否走索引,取决于查询条件是否匹配索引结构。
- 单列索引适用高频等值查询字段,如
status、type:CREATE INDEX idx_order_status ON order(status) - 联合索引更高效,但必须遵守最左前缀原则:如果建了
(user_id, status, create_time),那WHERE user_id = ?或WHERE user_id = ? AND status = ?能用,但WHERE status = ?就无法使用 - 把区分度高的列放左边(如 user_id 比 status 区分度高),把常用于范围查询的列放右边(如 create_time 适合放最后)
- 字符串字段过长时用前缀索引节省空间:
CREATE INDEX idx_title_50 ON article(title(50)),但需确认前 50 字符足以区分大多数值
实际落地要避开的坑
很多 Java 团队加了索引却没提速,甚至变慢,往往卡在这几个细节上:
- 别给低区分度字段单独建索引(如 gender、is_deleted),优化器大概率放弃使用,纯属浪费写入开销
- 大表加索引务必用在线 DDL:
ALTER TABLE t ADD INDEX idx_xxx(xxx), ALGORITHM=INPLACE, LOCK=NONE,避免锁表影响线上服务 - 每次上线新索引,一定要用
EXPLAIN看执行计划——确认 type 是 range/ref,key 显示索引名,rows 显著下降 - 定期清理未被使用的索引:
SELECT * FROM sys.schema_unused_indexes(需开启 performance_schema)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











