知用网
霓虹主题四 · 更硬核的阅读氛围

关联查询字段没索引会怎样

发布时间:2025-12-30 13:20:30 阅读:80 次

关联查询字段没索引会怎样

项目上线前做性能压测,突然发现一张表的查询慢得离谱。排查一圈才发现,两张表 JOIN 的条件字段居然一个没加索引。这种情况在开发中其实挺常见,尤其是初期数据量小,问题不明显,等用户一多,系统就开始卡了。

查询变慢是必然的

比如有张订单表 order,还有张用户表 user,通过 user_id 关联。如果 user 表的 user_id 没有索引,每次查某个用户的订单时,数据库就得全表扫描 user 表,哪怕只查一条记录,也得把整张表翻一遍。数据量小还好,一旦上十万、百万,响应时间直接从毫秒级飙到几秒甚至更久。

这就像去图书馆找一本书,如果没有目录,只能一本本翻过去看是不是你要的那本,效率自然低。

锁竞争加剧

没有索引的关联查询不仅慢,还容易引发锁的问题。尤其是在高并发场景下,长时间运行的查询会占用更多行锁或表锁,其他事务就得排队等。轻则请求堆积,重则出现死锁,系统直接报错。

比如两个请求同时更新不同用户的数据,但因为 user_id 没索引,更新操作变成了全表扫描加锁,结果互相堵住,谁也执行不了。

执行计划走偏

数据库优化器在生成执行计划时,会优先选择有索引的路径。如果关联字段没索引,优化器可能干脆放弃使用索引,转而采用嵌套循环或者哈希连接,但数据量一大,这些方式都撑不住。有时候还会错误地选择驱动表,导致小表去驱动大表全表扫描,雪上加霜。

举个实际例子

假设我们有两个表:

CREATE TABLE `user` (
`id` int(11) NOT NULL,
`name` varchar(50),
PRIMARY KEY (`id`)
);

CREATE TABLE `order` (
`id` int(11) NOT NULL,
`user_id` int(11),
`amount` decimal(10,2),
PRIMARY KEY (`id`)
);

INSERT INTO `order` VALUES (1, 1001, 99.9);
INSERT INTO `user` VALUES (1001, '张三');

现在执行这条查询:

SELECT o.amount, u.name 
FROM `order` o
JOIN `user` u ON o.user_id = u.id;

看起来没问题,但如果 user 表的 id 字段虽然是主键,但某些情况下(比如写错了关联字段),或者 user_id 没加索引,数据库就得对 user 表做全表扫描。explain 一看,type 是 ALL,rows 几万条,就知道出事了。

怎么避免这类问题

最简单的办法就是在做 JOIN 的字段上加索引。比如 order 表的 user_id,一定要加索引:

ALTER TABLE `order` ADD INDEX idx_user_id (user_id);

另外,上线前用 explain 分析关键 SQL 的执行计划,看看有没有全表扫描、有没有走索引。定期 review 慢查询日志,也能提前发现问题。

别等到用户投诉“怎么又卡了”,才想起来查数据库。一个小索引,省掉一堆半夜救火的功夫。