当前位置:首页 > 数码 > JOIN与IN的比拟-MySQL性能优化 (join与in的区别)

JOIN与IN的比拟-MySQL性能优化 (join与in的区别)

admin7个月前 (05-09)数码50

当天发现一篇很无心思的文章,经常使用查问时,是经常使用join好,还是间接in更好,这个大家上班时经常遇到。

为了繁难大家检查,文章我从新启动了排版。

我没有间接用作者的论断,觉得或者会误导读者,而是依据实验结果,给出我自己的倡导。

不BB,上目录:

图片

01背景

事件是这样的,去年入职的新公司,之后在代码review的时刻被提出说,不要写join,join耗性能还是慢来着,过后也是真的没有多想,那就写in好了。

最近发现in的数据量过大的时刻会造成sql慢,甚至sql太长,间接报错了。

这次来浅究一下,究竟是in好还是join好,仅目前认知探寻,有不对之处欢迎斧正。

以下实验仅在本机电脑实验。

02表结构

2.1用户表

图片

CREATETABLE`user`(`id`intNOTNULLAUTO_INCREMENT,`name`varchar(64)CHARACTERSETutf8mb4COLLATEutf8mb4_general_ciNOTNULLCOMMENT'姓名',`gender`smallintDEFAULTNULLCOMMENT'性别',`mobile`varchar(11)CHARACTERSETutf8mb4COLLATEutf8mb4_general_ciNOTNULLCOMMENT'手机号',`create_time`datetimeNOTNULLCOMMENT'创立期间',PRIMARYKEY(`id`),UNIQUEKEY`mobile`(`mobile`)USINGBTREE)ENGINE=InnoDBAUTO_INCREMENT=1005DEFAULTCHARSET=utf8mb4COLLATE=utf8mb4_general_ci

2.2订单表

图片

CREATETABLE`order`(`id`intunsignedNOTNULLAUTO_INCREMENT,`price`decimal(18,2)NOTNULL,`user_id`intNOTNULL,`product_id`intNOTNULL,`status`smallintNOTNULLDEFAULT'0'COMMENT'订单形态',PRIMARYKEY(`id`),KEY`user_id`(`user_id`),KEY`product_id`(`product_id`))ENGINE=InnoDBAUTO_INCREMENT=202DEFAULTCHARSET=utf8mb4COLLATE=utf8mb4_general_ci

03千条数据状况

数据量:用户表插一千条随机生成的数据,订单表插一百条随机数据

要求:查下一切的订单以及订单对应的用户

耗时权衡目的:多表衔接查问老本=一次性驱动表老本+从驱动表查出的记载数*一次性被驱动表的老本

selectorder.id,price,user.namefromorderjoinuseronorder.user_id=user.id;

图片

selectid,price,user_idfromorder;

图片

JOIN与IN的比拟

selectnamefromuserwhereidin(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并发场景

重要用原生写了脚本,用ab启动10个同时的恳求,看下期间,启动比拟。

>ab-n100-c10//口头脚本

上方是join查问的口头脚本:

$mysqli=newmysqli('127.0.0.1','root','root','test');if($mysqli->connect_error){die('ConnectError('.$mysqli->connect_errno.')'.$mysqli->connect_error);}$result=$mysqli->query('selectorder.id,price,user.`name`from`order`joinuseronorder.user_id=user.id;');$orders=$result->fetch_all(MYSQLI_ASSOC);var_dump($orders);$mysqli->close();

图片

上方是in查问的口头脚本:

$mysqli=newmysqli('127.0.0.1','root','root','test');if($mysqli->connect_error){die('ConnectError('.$mysqli->connect_errno.')'.$mysqli->connect_error);}$result=$mysqli->query('select`id`,price,user_idfrom`order`');$orders=$result->fetch_all(MYSQLI_ASSOC);$userIds=implode(',',array_column($orders,'user_id'));//失掉订单中的用户id$result=$mysqli->query("select`id`,`name`from`user`whereidin({$userIds})");$users=$result->fetch_all(MYSQLI_ASSOC);//失掉这些用户的姓名//将id做数组键$userRes=[];foreach($usersas$user){$userRes[$user['id']]=$user['name'];}$res=[];//整合数据foreach($ordersas$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条试下。

图片

order耗时:

图片

user耗时:

图片

4.3并发场景

join耗时:

图片

in耗时:

图片

数据量到达万级别,非并发场景,in更快,并发场景join更快。

05十万条数据状况

随机拔出后user表十万条数据,order表一百万条试下。

图片

order耗时:

图片

user耗时:

order查进去的结果过长了...

5.3并发场景

join耗时:

图片

in耗时:

图片

数据量到达十万/百万级别,非并发场景,in过长,并发场景join更快。

06总结

实验论断:

上方是楼仔给出的一些倡导。

当数据量比拟小时,倡导用in,只管两者的性能差不多,然而join会参与sql的复杂度,后续再变卦,会十分费事。

当数据量比拟大时,倡导用join,重要还是出于查问性能的思考。

不过经常使用join时,小表驱动大表,必定要建设索引,join的表最好不要超越3个,否则性能会十分差,还会大大参与sql的复杂度,十分不利于后续性能裁减。


在SQL联表查询的时候,in和inner join各有什么优点?

in后面跟的是一些确定的数据或值,inner join是内连接,联表时的一种

在SQL联表查询的时候,in和inner join各有什么优点?

大概举例如下:比如A1表 100W行 A2表50W行select a.* from A1 a where 1 in (select 1 from A2 b where 2=xxx);select a.* from A1 a where exists (select x from A2 b where 2=xxx and 1=1);select a.* from A1 a,A2 b where 2=xxx and 1=1在(select from A2 b where 2=xxx)的结果集比较小的情况下(比如只有几十条)用in的效率高于关联,如果结果集比较大的情况下则用join的效率高于用in,这里我还列举了exists,这个效率类似于join也是结果集大的情况下适用,至于两者的拐点还需要你在执行计划和统计信息当中去观察以便确定出最优的sql语句。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: MySQL

“JOIN与IN的比拟-MySQL性能优化 (join与in的区别)” 的相关文章

MySQL-一探究竟-核心模块揭秘 (mysql-bin文件可以删除吗)

MySQL-一探究竟-核心模块揭秘 (mysql-bin文件可以删除吗)

Undo Segment Caching To improve the efficiency of undo segmentallocation, InnoDB caches some un...

优化数据统计的终极指南-MySQL-提升查询性能的秘诀 (优化数据统计工具)

优化数据统计的终极指南-MySQL-提升查询性能的秘诀 (优化数据统计工具)

在业务场景中,我们经常需要统计当前已有的业务数据,例如商品库内商品的数量、每天的用户订单数量等。此时,我们需要使用统计功能来实现。 count()实现方式 对于不同的数据库引擎,co...

实战-MySQL-数据库压力测试与性能评估方法-Java (实战篮球鞋排名)

实战-MySQL-数据库压力测试与性能评估方法-Java (实战篮球鞋排名)

压力测试的目的和重要性 压力测试是模拟真实环境中并发用户访问数据库的场景,通过增加负载来测试数据库系统的性能表现。压力测试的目的是发现数据库在高负载下的性能瓶颈、资源利用情况和响应时间等指...

主从复制原理简介-MySQL (主从复制原理mysql)

主从复制原理简介-MySQL (主从复制原理mysql)

主从复制(Master-SlaveReplication)是一种数据复制技术,用于在多个数据库主机之间的数据同步。在主从复制架构中,一个主机被设置为主主机(Master),充任数据源,其余主机被设...

全面指南-如何解决-MySQL-主从延时问题 (全面指导)

全面指南-如何解决-MySQL-主从延时问题 (全面指导)

一、什么是主从延时? 主从延时,是指从数据库从主数据库复制数据时产生的时间差。它会导致从库中的数据与主库不一致。 二、为什么会主从延时? 1. 主从复制原理 MySQL的...

核心模块-深入探索数据库引擎-MySQL-揭秘 (核心模块英文)

核心模块-深入探索数据库引擎-MySQL-揭秘 (核心模块英文)

简介 Savepoint 是 MySQL 中的一种机制,允许在事务中创建标记点,以便在事务失败时回滚到该标记点。Savepoint 的原理是将事务的当前状态存储在各种数据结构中,包括服务器层、b...

使用-数据库并自动发送备份文件到指定邮箱-K8s-定期备份-MySQL (使用数据库的命令)

使用-数据库并自动发送备份文件到指定邮箱-K8s-定期备份-MySQL (使用数据库的命令)

简介 本文档描述了一个使用脚本来监控服务器高占用率进程并通过电子邮件发送警报的项目。本文还探讨了使用相同机制备份数据库的可能性。 技术 Python psuti...

EXPLAIN-代价模型-MySQL-浅析-提早预知索引优化战略-优化查问性能-告别自觉经常使用 (explain)

EXPLAIN-代价模型-MySQL-浅析-提早预知索引优化战略-优化查问性能-告别自觉经常使用 (explain)

背景 在中,当咱们为表创立了一个或多个索引后,通常须要在索引定义成功后,依据详细的数据状况口头EXPLN命令,才干观察到数据库实践经常使用哪个索引、能否经常使用索引。这使得咱们在参与新索引之...