mysql到底是join性能好,还是in一下更快呢?

发布时间:2026/9/1 16:49:57
mysql到底是join性能好,还是in一下更快呢? 今天发现一篇很有意思的文章使用 mysql 查询时是使用 join 好还是直接 in 更好这个大家工作时经常遇到。为了方便大家查看文章我重新进行了排版。我没有直接用作者的结论感觉可能会误导读者而是根据实验结果给出我自己的建议。01 背景事情是这样的去年入职的新公司之后在代码 review 的时候被提出说不要写 joinjoin 耗性能还是慢来着当时也是真的没有多想那就写 in 好了。最近发现 in 的数据量过大的时候会导致 sql 慢甚至 sql 太长直接报错了。这次来浅究一下到底是 in 好还是 join 好仅目前认知探寻有不对之处欢迎指正。以下实验仅在本机电脑试验。02 表结构2.1 用户表CREATE TABLE user ( id int NOT NULL AUTO_INCREMENT, name varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 姓名, gender smallint DEFAULT NULL COMMENT 性别, mobile varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 手机号, create_time datetime NOT NULL COMMENT 创建时间, PRIMARY KEY (id), UNIQUE KEY mobile (mobile) USING BTREE ) ENGINEInnoDB AUTO_INCREMENT1005 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_general_ci2.2 订单表CREATE TABLE order ( id int unsigned NOT NULL AUTO_INCREMENT, price decimal(18,2) NOT NULL, user_id int NOT NULL, product_id int NOT NULL, status smallint NOT NULL DEFAULT 0 COMMENT 订单状态, PRIMARY KEY (id), KEY user_id (user_id), KEY product_id (product_id) ) ENGINEInnoDB AUTO_INCREMENT202 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_general_ci03 千条数据情况数据量用户表插一千条随机生成的数据订单表插一百条随机数据要求查下所有的订单以及订单对应的用户耗时衡量指标多表连接查询成本 一次驱动表成本 从驱动表查出的记录数 * 一次被驱动表的成本3.1 joinselect order.id, price, user.name from order join user on order.user_id user.id;3.2 inselect id,price,user_id from order;select name from user where id in (8, 11, 20, 32, 49, 58, 64, 67, 97, 105, 113, 118, 129, 173, 179, 181, 210, 213, 215, 216, 224, 243, 244, 251, 280, 309, 319, 321, 336, 342, 344, 349, 353, 358, 363, 367, 374, 377, 380, 417, 418, 420, 435, 447, 449, 452, 454, 459, 461, 472, 480, 487, 498, 499, 515, 525, 525, 531, 564, 566, 580, 584, 586, 592, 595, 610, 633, 635, 640, 652, 658, 668, 674, 685, 687, 701, 718, 720, 733, 739, 745, 751, 758, 770, 771, 780, 806, 834, 841, 856, 856, 857, 858, 882, 934, 942, 983, 989, 994, 995);其中 in 的是order查出来的所有用户 id。如此看来分开查和 join 查的成本并没有相差许多。3.3 并发场景主要用php原生写了脚本用ab进行10个同时的请求看下时间进行比较。 ab -n 100 -c 10 // 执行脚本下面是 join 查询的执行脚本$mysqli new mysqli(127.0.0.1, root, root, test); if ($mysqli-connect_error) { die(Connect Error ( . $mysqli-connect_errno . ) . $mysqli-connect_error); } $result $mysqli-query(select order.id, price, user.name from order join user on order.user_id user.id;); $orders $result-fetch_all(MYSQLI_ASSOC); var_dump($orders); $mysqli-close();下面是 in 查询的执行脚本$mysqli new mysqli(127.0.0.1, root, root, test); if ($mysqli-connect_error) { die(Connect Error ( . $mysqli-connect_errno . ) . $mysqli-connect_error); } $result $mysqli-query(select id,price,user_id from order); $orders $result-fetch_all(MYSQLI_ASSOC); $userIds implode(,, array_column($orders, user_id)); // 获取订单中的用户id $result $mysqli-query(select id,name from user where id in ({$userIds})); $users $result-fetch_all(MYSQLI_ASSOC);// 获取这些用户的姓名 // 将id做数组键 $userRes []; foreach ($users as $user) { $userRes[$user[id]] $user[name]; } $res []; // 整合数据 foreach ($orders as $order) { $current []; $current[id] $order[id]; $current[price] $order[price]; $current[name] $userRes[$order[user_id]] ?: ; $res[] $current; } var_dump($res); // 关闭mysql连接 $mysqli-close();看时间的话明显 join 更快一些。04 万条数据情况user表现在10000条数据order表10000条试下。4.1 join4.2 inorder 耗时user 耗时4.3 并发场景join 耗时in 耗时数据量达到万级别非并发场景in 更快并发场景 join 更快。05 十万条数据情况随机插入后user表十万条数据order表一百万条试下。5.1 join5.2 inorder 耗时user 耗时order查出来的结果过长了...5.3 并发场景join 耗时in 耗时数据量达到十万/百万级别非并发场景in 过长并发场景 join 更快。06 总结实验结论数据量不到万级别join 和 in 差不多数据量达到万级别非并发场景in 更快并发场景 join 更快数据量达到十万/百万级别非并发场景in 过长并发场景 join 更快。下面是楼仔给出的一些建议。当数据量比较小时建议用 in虽然两者的性能差不多但是 join 会增加 sql 的复杂度后续再变更会非常麻烦。当数据量比较大时建议用 join主要还是出于查询性能的考虑。不过使用 join 时小表驱动大表一定要建立索引join 的表最好不要超过 3 个否则性能会非常差还会大大增加 sql 的复杂度非常不利于后续功能扩展。

相关新闻