iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >一文教你MySQL如何优化无索引的join
  • 561
分享到

一文教你MySQL如何优化无索引的join

2024-04-02 19:04:59 561人浏览 薄情痞子
摘要

目录前言遍历循环查询join 查询join buffer (Block Nested Loop)附:Mysql  join查询没有走索引的原因总结前言 mysql Join

前言

mysql Join 你用过吗?你知道其中的原理吗?

现在有张 user 表,这个 user 表很简单,一个主键 id,也就是我们的用户 id,还有个 name 字段,很明显就是用户的姓名。

这时候还有一张 user_info 表,这个 user_info 表存的是用户的一些其他信息,有 user_id 代表用户的 id,还有个 account 代表用户的存款。

遍历循环查询

如果要查出所有用户的姓名和存款,我们可以这样查:

data = select * from user;
for (i=0;i<len(data);i++) {
  info = select account from user_info where user_id= data[i].user_id
}

这种方式最直观,先通过 user 表拿到所有的用户信息,然后根据连接键 user_id 去 user_info 表里查询对应的 account,这样就能得到想要的数据,但是这种方式几个问题:

  • 第一次全表扫描 user 表需要一次网络通信,假设 user 表的数据量是n。

  • 然后循环查询 user_info 表,这里需要 n 次网络通信

因此一共需要 n+1 次网络通信,如果使用的是长连接,还能省去 3 次握手的时间,如果是短连接,整体的开销会更大。

其次如果 user_id 没有索引,那么整体更伤,假设 user_info 一共有 m 条数据,那么扫描的次数是怎么算的呢?

  • 首先 user 表是全表扫,一共需要查询 n 次。

  • 由于 user_info 表的 user_id 没有索引,那么每次查询等于都是全表扫,总共需要 n*m 次。

因此这种查询的方式一共需要扫描 n+n*m 次。当然一般不会出现 user_id 没有索引的情况,在 user_id 有索引的时候,可以根据索引快速定位到我们的目标数据,并不需要全表扫描,因此总共需要扫描的行数为 n+m 次。

join 查询

一般对于这种情况的查询,我们会用 join 来做,于是我们的 sql 或许如下:

select a.name,b.account from user a left join user_info b on a.id=b.user_id

首先从网络通信上来说,总体只需要一次通信,至于 MySQL 内部怎么处理数据,怎么把我们想要的数据返回回来是它内部的事。

其次我们来看看这种 join 方式的原理:

  • 从 user 表扫描一条数据,然后去 user_info 表中匹配

  • 在连接键 user_id 有索引的情况下,可以利用索引快速匹配

  • 然后把 user 表中的 name 和 user_info 表中的 account 作为结果集的一部分返回回去

  • 重复 1-3 步骤,直至 user 表扫描完毕,数据全部返回。

其中第三步骤,每次组合一条数据的时候,并不是立马返回给客户端,这样效率太低,其实是有缓冲区的,也就是先把数据放在缓冲区中,等缓冲区满了,一次性响应给客户端可以大大提升效率。

从原理来看和上面的遍历查询差不多,主要不同的是,客户端不需要和服务端多次通信。

join buffer (Block Nested Loop)

以上说的还是连接键有索引的,我们来看看连接键没有索引的情况,这时候你通过 explain 来看 MySQL 的执行计划,你会发现其中 user_info 的 extra 字段中会提示这个:

Using where; Using join buffer (Block Nested Loop)

这是什么意思呢?

因为没有索引,所以每次去 user 表得到一条数据的时候,肯定是要再到 user_info 表做全表扫描,这个扫描的成本我们上面也提到了,就是 n+n*m=n(1+m),因此这个时间复杂度是和 n 成正比的,这也是为什么我们一般推荐「小表驱动大表」的方式。

但是如果我们按照这个方式来做 join,未免开销太大了,太耗时了,于是还是沿用老套路,也就是用个临时存储区,也就是 extra 中的 join buffer,有了这个 join buffer 后,首先会把 user 表的数据放进去,然后扫描 user_info 表,每扫描一行数据,就和 join buffer 中的每一行 user 数据匹配,如果匹配上了,也就是我们要的结果,因为 user_info 表有 m 条数据,因此需要判断 n*m 次,咦!这个也没减少呀,还是和上面的一样。其实不一样,这里的 m 条数据其实每次都是和内存中的 n 条数据做匹配的,并非磁盘,内存的速度不用多说。

聪明的读者可能会发现,如果 user 表的数据很多,join buffer 能放得下吗?

+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| join_buffer_size | 262144 |
+------------------+--------+

buffer 默认是 256K,多的话确实放不下,放不下的话,怎么办?其实也很简单,分段放即可,当读 user 表的数据占满 buffer 的时候,就不放了,然后直接和 user_info 做匹配,逻辑还是同上,在 buffer 的数据处理完之后,就清空它,接着上次的位置继续读入数据,再次重复同样的逻辑,直至数据读完。

虽说连接键没有索引的时候,会通过 join buffer 来优化速度,但是现实中,还是建议大家尽量要保证连接键有索引。

附:mysql  join查询没有走索引的原因

把行数最小的作为主表,然后去join行数多的,这样对于索引而言扫描的行数会少很多

在join之后On的条件,类型不同是无法走索引的,也就是说如果on A.id = B.id,虽然A表和B表的id都设置了索引,但是A表的id是Int,而B表的id是varchar,则无法走索引

字符编码也会导致无法走索引。字符编码常见的是utf8和utf8mb4,utf8mb4是可以兼容utf8的,也就是说如果A表是utf8mb4,B表是utf8,则on A.uinstanceid = B. uinstanceid是可以走索引的,但是如果把B表当作主表,让B去join A on B.uinstanceid = A. uinstanceid则无法走索引

在我的项目里,就是上面的字符编码问题导致的join后没有走索引

改表和字段的字符编码,统一成ut8mb4

ALTER TABLE visitor DEFAULT CHARSET utf8mb4;
ALTER TABLE visitor CHANGE visitor_id visitor_id varchar(100) CHARACTER SET utf8mb4 NOT NULL DEFAULT '';

总结

到此这篇关于MySQL如何优化无索引join的文章就介绍到这了,更多相关MySQL优化无索引join内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文档:

--结束END--

本文标题: 一文教你MySQL如何优化无索引的join

本文链接: https://www.lsjlt.com/news/163506.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 一文教你MySQL如何优化无索引的join
    目录前言遍历循环查询join 查询join buffer (Block Nested Loop)附:mysql  join查询没有走索引的原因总结前言 MySQL Join...
    99+
    2024-04-02
  • MySQL怎么优化无索引的join
    MySQL怎么优化无索引的join,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。前言MySQL Join 你用过吗?你知道其中的原理吗?现在有张 user 表,...
    99+
    2023-06-28
  • Mysql索引如何优化
    小编给大家分享一下Mysql索引如何优化,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!编程沉思录     &...
    99+
    2024-04-02
  • MySQL中的索引如何优化
    这篇文章主要介绍了MySQL中的索引如何优化的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇MySQL中的索引如何优化文章都会有所收获,下面我们一起来看看吧。使用索引优化索引是数...
    99+
    2023-03-01
    mysql
  • MySQL中如何优化索引
    MySQL中如何优化索引,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。文章的脑图如下:索引优化规则1、like语句的前导模糊查询不能使用索...
    99+
    2024-04-02
  • 一文详解MySQL—Join的使用优化
    目录mysql JOIN类型MySQL JOIN 算法Nested-Loop Join 算法执行流程工作原理时间复杂度分析block Nested-Loop Join 算法执行流程工作原理时间复杂度分析Hash Join...
    99+
    2023-04-21
    MySQL Join使用 MySQL Join优化 MySQL Join
  • MySQL索引如何进行优化
    这篇文章主要介绍了MySQL索引如何进行优化,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。  创建 test 测试表  CREATE TAB...
    99+
    2024-04-02
  • MySQL索引管理优化的方法教程
    这篇文章主要讲解了“MySQL索引管理优化的方法教程”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MySQL索引管理优化的方法教程”吧! ...
    99+
    2024-04-02
  • 一文教你JavaScript如何实现分支优化
    以上就是一文教你JavaScript如何实现分支优化的详细内容,更多请关注编程网其它相关文章!...
    99+
    2022-11-22
    javascript
  • mysql中索引配置如何优化
    这篇文章将为大家详细讲解有关mysql中索引配置如何优化,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 2     索引及查询优...
    99+
    2024-04-02
  • 如何使用索引优化你的网站SEO?
    SEO(搜索引擎优化)是网站推广中的一项重要工作,它可以帮助网站在搜索引擎中获得更好的排名,从而获得更多的流量和曝光度。在SEO中,索引是一个非常重要的概念,本文将介绍如何使用索引优化你的网站SEO。 一、什么是索引 在搜索引擎中,索引是指...
    99+
    2023-06-09
    异步编程 自然语言处理 索引
  • MySQL中如何创建和优化索引
    在MySQL中,可以使用CREATE INDEX语句来创建索引。例如,要在名为table_name的表中创建一个名为index_na...
    99+
    2024-04-09
    MySQL
  • MySql中的Full Text Search全文索引优化
    目录开篇一个简单的DEMO天下没有免费的午餐无索引使用 B 树索引引入反向索引在默认解析器中使用反向索引在 n-gram 解析器中使用反向索引InnoDB 反向索引性能下降备选方案开篇 在我们的生产环境中,有一个模糊检索...
    99+
    2023-05-12
    MySql全文索引优化 MySql全文索引优化
  • Python文件索引:从基础到实战,一步步教你实现文件加载优化。
    Python文件索引:从基础到实战,一步步教你实现文件加载优化 随着程序规模的不断扩大,文件的加载和访问成为了一个越来越重要的问题。在Python中,我们经常需要加载各种模块和文件,而这些文件又可能会相互依赖,导致加载顺序的不确定性和性能瓶...
    99+
    2023-09-28
    文件 索引 load
  • MySql中的Full Text Search全文索引优化
    目录开篇一个简单的DEMO天下没有免费的午餐无索引使用 B 树索引引入反向索引在默认解析器中使用反向索引在 n-gram 解析器中使用反向索引InnoDB 反向索引性能下降备选方案开...
    99+
    2023-05-20
    MySql全文索引优化 MySql Full Text Search
  • Java 索引教程:如何使用 NPM 来优化搜索?
    在开发 Java 应用程序时,搜索是一个非常常见的需求。然而,如果数据量很大,普通的搜索算法可能会变得非常缓慢。为了解决这个问题,我们可以使用索引来优化搜索。在本教程中,我们将介绍如何使用 NPM 来构建索引,并使用索引来加快搜索速度。 ...
    99+
    2023-07-27
    索引 教程 npm
  • 索引:如何优化你的数据库查询速度?
    在现代的应用程序中,数据库是非常重要的一部分。然而,随着数据量的增长,查询速度的下降也会成为一个问题。这时候,索引就成为了一个非常重要的工具。在本文中,我们将介绍什么是索引,以及如何使用它来优化你的数据库查询速度。 什么是索引? 索引可以...
    99+
    2023-06-09
    异步编程 自然语言处理 索引
  • mysql中如何进行联合索引优化
    今天就跟大家聊聊有关mysql中如何进行联合索引优化,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。  exp...
    99+
    2024-04-02
  • 一文教你如何优雅的使用WebSocket
    目录简介特性使用场景具体实现一、首先是服务端代码,这里我用的是nodejs。二、然后是客户端代码总结简介 websocket是基于TCP的一种双向通信协议。在此之前,一直是采用轮询的...
    99+
    2024-04-02
  • 如何通过索引优化PHP与MySQL的全文检索和排序查询?
    在开发互联网应用程序中,全文检索和排序查询是常见的需求。对于大量数据的查询操作来说,优化索引是提高数据库性能的重要手段之一。在PHP与MySQL的组合中,我们可以通过合理使用索引,来提高全文检索和排序查询的效率。本文将介绍如何通过索引优化P...
    99+
    2023-10-21
    MySQL PHP 索引优化
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作