返回顶部
首页 > 资讯 > 数据库 >MySQL怎么优化无索引的join
  • 956
分享到

MySQL怎么优化无索引的join

2023-06-28 23:06:26 956人浏览 安东尼
摘要

MySQL怎么优化无索引的join,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。前言Mysql Join 你用过吗?你知道其中的原理吗?现在有张 user 表,

MySQL怎么优化索引的join,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。


    前言

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

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

    MySQL怎么优化无索引的join

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

    MySQL怎么优化无索引的join

    遍历循环查询

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

    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 '';

    看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网数据库频道,感谢您对编程网的支持。

    您可能感兴趣的文档:

    --结束END--

    本文标题: MySQL怎么优化无索引的join

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

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

    猜你喜欢
    • MySQL怎么优化无索引的join
      MySQL怎么优化无索引的join,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。前言MySQL Join 你用过吗?你知道其中的原理吗?现在有张 user 表,...
      99+
      2023-06-28
    • 一文教你MySQL如何优化无索引的join
      目录前言遍历循环查询join 查询join buffer (Block Nested Loop)附:mysql  join查询没有走索引的原因总结前言 MySQL Join...
      99+
      2024-04-02
    • mysql索引怎么优化
      1. 使用合适的数据类型:选择合适的数据类型可以减小索引的大小,提高查询速度。例如,使用INT类型代替VARCHAR类型存储数字字段...
      99+
      2024-02-29
      mysql
    • MySQL索引优化
      一、单表 创建索引之前:type=ALL全表扫描,Extra里面的Using filesort(文件内部排序) 根据where后面的条件创建:CREATE INDEX idx_article_ccv ON articl...
      99+
      2019-01-06
      MySQL索引优化
    • mysql日期索引怎么优化
      要优化MySQL的日期索引,可以尝试以下几种方法: 确保日期列的数据类型为日期类型,例如DATETIME或DATE,而不是字符串...
      99+
      2024-02-29
      mysql
    • mysql织梦索引优化之MySQL Order By索引优化
      在一些情况下,MySQL可以直接使用索引来满足一个ORDER BY 或GROUP BY 子句而无需做额外的排序。尽管ORDER BY 不是和索引的顺序准确匹配,索引还是可以被用到,只要不用的索引部分和所有的额外的ORDER B...
      99+
      2024-04-02
    • 怎么进行MySQL性能优化中的索引优化
      本篇文章为大家展示了怎么进行MySQL性能优化中的索引优化,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。大家都知道索引对于数据访问的性能有非常关键的作用,都知道索引...
      99+
      2024-04-02
    • MySQL索引优化EXPLAIN
      日常在CURD的过程中,都避免不了跟数据库打交道,大多数业务都离不开数据库表的设计和SQL的编写,那如何让你编写的SQL语句性能更优呢? 先来整体看下MySQL逻辑架构图: MySQL整体逻辑架构图可以分为Server和存储引擎层。...
      99+
      2015-10-24
      MySQL索引优化EXPLAIN
    • MySQL优化(3):索引
      MySQL优化中,最重要的优化手段就是索引,也是最常用的优化手段   索引简介: 索引:关键字与数据位置之间的映射关系 关键字:从数据中提取,用于标识,检索数据的特定内容 目的:加快检索   索引检索为什么快: (1)关键字相对于...
      99+
      2014-05-17
      MySQL优化(3):索引
    • MySQL优化之索引
      SQL为什么需要优化? 对于初学者来说,能够写出实现功能的SQL语句而不出错,查询出所需要的结果,就已经能够满足日常使用了。但在某些场景,对性能的要求比较高,因此,要求SQL的执行响应速度快,就需要对SQL进行一定程度的优化。 在...
      99+
      2021-02-14
      MySQL优化之索引
    • mysql优化和索引
      表的优化1.定长与变长分离    如 int,char(4),time核心且常用字段,建成定长,放在一张表;    而varchar,text,blob这种...
      99+
      2024-04-02
    • centos7-mysql-索引优化
      索引优化,优化查询速度-------------------------------------------------------count,统计一个表总计行数myisam储存引擎有自带计数器,使用cou...
      99+
      2024-04-02
    • MySQL 5.7 索引优化
      提升查询性能最好的方法就是创建索引。索引项就像指向表中行的指针,让查询通过WHERE条件快速找到所要查询的行。MySQL所有的数据类型都可以创建索引。 不必要的索引会消耗系统的空间和MySQL在判断...
      99+
      2024-04-02
    • MySQL中怎么实现索引优化
      MySQL中怎么实现索引优化,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。建表// 建表  CREATE&nbs...
      99+
      2024-04-02
    • MySQL中怎么使用索引优化
      本篇内容主要讲解“MySQL中怎么使用索引优化”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL中怎么使用索引优化”吧!使用索引优化索引是数据库优化最常用也是最重要的手段之一,通过索引通常...
      99+
      2023-07-05
    • Mysql索引该怎么设计与优化
      小编给大家分享一下Mysql索引该怎么设计与优化,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!什么是索引?数据库索引是一种数据结构,它以额外的写入和存储空间为代价来提高数据库表上数据检索操作的速度。通俗来说,索引类似于书的...
      99+
      2023-06-08
    • MySQL索引优化分享
      2,explain的作⽤ 查看表的读取顺序,读取操作类型,有哪些索引可用,表之间关联,每张表中有哪些索引被优化器执⾏ 3,索引命中策略略分析     最左匹配原则 在索引字段上加入函数(不匹配索引)     is null/is not n...
      99+
      2016-09-28
      MySQL索引优化分享
    • MySQL索引优化深入
      创建 test 测试表 CREATE TABLE `test` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `c1` varchar(10) DEFAULT NULL,  `c2`...
      99+
      2016-11-27
      MySQL索引优化深入
    • MySQL如何优化索引
      1.  MySQL如何使用索引 索引用于快速查找具有特定列值的行。如果没有索引,MySQL必须从第一行开始,然后遍历整个表以找到相关的行。表越大,花费越多。如果表中有相关列的索引,MySQL可以快速确定要在...
      99+
      2022-05-27
      MySQL 索引 MySQL 优化索引
    • MySQL 索引优化案例
      目录数据准备联合索引的首字段用范围查询强制走索引覆盖索引优化in和or什么时候会走索引like xx% 一般都会走索引,和数据量无关索引下推为什么范围查找没有用索引下推优化?如何选择索引Trace 工具深入优化order...
      99+
      2022-08-19
      MySQL索引优化 MySQL索引
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作