当前位置:网站首页>Mysql使用left join连表查询时,因连接条件未加索引导致查询很慢
Mysql使用left join连表查询时,因连接条件未加索引导致查询很慢
2022-07-28 14:02:00 【51CTO】
背景
最近一个后台功能列表,业务人员反馈查询和导出速度非常慢。
通过定位发现列表查询和数据导出都是使用的同样的一个连表查询SQL。
这个功能刚上线不久,起初查询和导出速度都是蛮快的,把这个SQL放到测试环境也是挺快的。
对比了一下测试环境和生产环境相关表结构都是一样的,之后我们把目光放在了数量的问题上面,但是几张关联表的数据量也不大,不到1w的数据量为何会这么慢呢。
排查
通过Explain发现,连表查询中的table c没有使用到索引且是全表扫描。另外在Extra中特别说明了Using join buffer (Block Nested Loop)。
其中table c中的filtered=100% 表示右表没有应用索引下推(ICP),因为where条件没有索引。
另外Using join buffer (Block Nested Loop)是因为右表没有在join列上建索引导致嵌套循环。

解决
通过对table c中的连接字段content_id和user_no分别加上了索引,
加上索引后的执行计划如下

总结
需要注意:参与join的表,需要在连接条件上建索引。
知识延伸
MySQL使用嵌套循环算法或其变种来进行表之间的连接。
在5.5版本之前,MySQL只支持一种表间关联方式,也就是嵌套循环(Nested Loop)。如果关联的表数据量很大,那么join关联的时间会很长。在5.5版本以后,MySQL引入了BNL算法来优化嵌套循环。
1.嵌套循环连接算法(Nested-Loop Join Algorithm)
一个简单的嵌套循环连接(NLJ)算法从循环中的第一个表中逐行读取一行,将每行传递给处理连接中下一个表的嵌套循环。 这个过程会重复多次,因为还有剩余的表被连接。
假定要使用以下连接类型执行三个表t1,t2和t3之间的连接:
如果使用一个简单的NLJ算法,连接就像这样处理:
如图所示

这种算法缺陷也很明显,随着join表数量的增加,计算量呈指数上升。如果其中出现了一张数据量很大的表,对整个过程的效率也影响很大。
于是,mysql5.5对这个算法进行了优化,新增了Index Nested-loop Join,Block Nested-loop Join。
2.索引嵌套循环连接算法(Index Nested-loop Join Algorithm)
Index Nested-loop Join是针对有索引的情况,而Block Nested-loop Join是针对没有命中索引的情况。

由于索引的效率要比逐条循环效率高,所以当使用索引联表时,能大大加快查询速度,但是索引也不是万能的,如果你需要取索引以外的字段,那么依旧需要回到表中查出相应的数据。
3.块嵌套循环连接算法(Block Nested-Loop Join Algorithm)
Block Nested-loop Join 块嵌套循环(BNL)连接算法使用在外部循环中读取的行的缓冲来减少必须读取内部循环中的表的次数。
举个简单的例子:外层循环结果集有1000行数据,使用NLJ算法需要扫描内层表1000次,但如果使用BNL算法,则先取出外层表结果集的100行存放到join buffer, 然后用内层表的每一行数据去和这100行结果集做比较,可以一次性与100行数据进行比较,这样内层表其实只需要循环1000/100=10次,减少了9/10。

参考文章:
http://blog.sina.com.cn/s/blog_a1e9c7910102x1bz.html
本篇文章如有帮助到您,请给「翎野君」点个赞,感谢您的支持。

作者:翎野君
如果您喜欢或希望看到更多我的文章,关注我的微信公众号《翎野君》。
转载文章请务必保留出处和署名,否则保留追究法律责任的权利。
边栏推荐
- The second pre class exercise
- 1st pre class exercise
- (function(global,factory){
- C language: mathematical method of converting decimal system into binary system
- How long can we "eat" the dividends of domestic databases?
- Multi merchant mall system function disassembly lecture 17 - platform side order list
- Digital transformation security issues occur frequently, and Shanshi Netcom helps build a digital government
- 16、 Launch file label of ROS (II)
- The third pre class exercise
- MLX90640 红外热成像仪传感器模块开发笔记(八)
猜你喜欢

Product Manager

Chapter 3 stack, queue and array

国产数据库的红利还能“吃”多久?

6、 C language circular statement
![[complete installation package & tutorial] sqlserver basic installation_ Sqlserver completely uninstalled_ Sqlserver custom installation_ Getting started with sqlserver_ SQLSERVER database](/img/72/d3e46a820796a48b458cd2d0a18f8f.png)
[complete installation package & tutorial] sqlserver basic installation_ Sqlserver completely uninstalled_ Sqlserver custom installation_ Getting started with sqlserver_ SQLSERVER database

VTK vtkcontourwidget extracts regions of interest

Qt development tips

Simple data analysis using Weka and excel

Redis-持久化

Getting started with scottplot tutorial: getting and displaying values at the mouse
随机推荐
QT serialization qdatastream
PS modify the length and width pixels and file size of photos
Machine learning related concepts
Matlab load usage
MLX90640 红外热成像仪传感器模块开发笔记(八)
Vtkcellpicker picking triangular patches
Swiftui layout - size (top)
Install scikit learn journey
Picture Trojan principle production prevention
[complete installation package & tutorial] sqlserver basic installation_ Sqlserver completely uninstalled_ Sqlserver custom installation_ Getting started with sqlserver_ SQLSERVER database
9、 C array explanation
VTK annotation class widget vtkborderwidget
SwiftUI 4.0 的全新导航系统
Introduction to MITK
Switch the cloud synchronization status of core data in real time
[thread safety] what risks may multithreading bring?
How many ways can multithread run in sequence?
How to reduce the resolution of only 3D camera but not UI camera
实时切换 Core Data 的云同步状态
C language: mathematical method of converting decimal system into binary system