介绍临时表之前,我们首先来看这么一句语句:

CREATE TABLE `words` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`word` varchar(64) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;

这是一个单词表,除了一个主键id之外,只有一个word字段,再来看下面这段sql:

select word from words order by rand() limit 3;

这段sql的语义其实就是按照随意的规则进行排序,然后取出前三个单词并返回,这段sql看起来很简单,但实际上要做的事还是比较繁琐的:

(1)创建一个临时表。这个临时表使用的是 memory 引擎,表里有两个字段,第一个字段是 double 类型,为了后面描述方便,记为字段 R,第二个字段是 varchar(64) 类型,记为字段 W。并且,这个表没有建索引。从 words 表中,按主键顺序取出所有的 word 值。

(2)对于每一个 word 值,调用 rand() 函数生成一个大于 0 小于 1 的随机小数,并把这个随机小数和 word 分别存入临时表的 R 和 W 字段中,到此,扫描行数是 10000。

(3)现在临时表有 10000 行数据了,接下来你要在这个没有索引的内存临时表(memory引擎的特性之后再说)上,按照字段 R 排序。

(4)初始化 sort_buffer。sort_buffer 中有两个字段,一个是 double 类型,另一个是整型。从内存临时表中一行一行地取出 R 值和位置信息(我后面会和你解释这里为什么是“位置信息”),分别存入 sort_buffer 中的两个字段里。这个过程要对内存临时表做全表扫描,此时扫描行数增加 10000,变成了 20000。

(5)在 sort_buffer 中根据 R 的值进行排序。注意,这个过程没有涉及到表操作,所以不会增加扫描行数。排序完成后,取出前三个结果的位置信息,依次到内存临时表中取出 word 值(这里还是有涉及到回表的操作,但是是回的内存表,所以没有磁盘io的消耗),返回给客户端。这个过程中,访问了表的三行数据,总扫描行数变成了 20003。

  当然除了内存临时表之外还有磁盘临时表,磁盘临时表是在内存不足时才会产生,所以尽可能的保证内存临时表的空间要足够大,否则磁盘的操作要比内存的操作要耗时的多!!

  OK,我们再来看一个例子,首先定义一下表结构:

create table t1(id int primary key, a int, b int, index(a));

现在我们有这么一个sql:

explain select b,count(*) as c from t1 group by b

sql的语义很简单,对b字段进行分组,并且通过聚合函数统计每个组的个数并返回,但是需要注意的是b字段没有建立索引,于是返回的结果里:

  可以看到有使用到临时表,但是后面居然还跟了个using filesort,这是为啥??我们可以先来看一下这句sql的执行流程:

(1)创建内存临时表,表里有两个字段 b 和 c,主键是 m;扫描表 t1,依次取出b的值;

(2)如果临时表中没有对应的b的值的行,就插入一个记录 (x,1);如果表中有对应的b的值的行,就将这一行的 c 值加 1;遍历完成后,再根据字段 b 做排序,得到结果集返回给客户端;

  注意到了没,最后有一步是对b做排序,这一步是在内存中的sort_buffer区域完成的,这一步的诞生导致了using filesort,但是我们的sql寓意里并不需要排序啊,那么可以使用order by null使得group by 之后不需要做任何排序,执行完成后你会发现using filesort消失了。。。但是using temporary还是在的,那么我们可以尝试在b字段加索引,继续执行上面的sql,如果b有索引的话,那么b索引树的肯定是这样子的:

  1-2-2-2-5-5-5-5
  是一个有序的链表,mysql在扫描这个索引时,直接轧过去,到2的时候自然知道1的个数只有一个,到5的时候自然知道2的个数只有3个,统计的复杂度就是n,但是如果m没有索引,那么就是无序的,在统计时,扫到2的时候,得去一个中间表看是否存在,存在+1,不存在添加。。。到这里也就清晰了,因为b有了索引,所以这个统计操作,只需要遍历一遍索引即可:

可以看到临时表没有再使用了,因为有了索引后,b字段不再需要临时表进行辅助统计,结果perfect!

  最后再提一提关于distinct和group by

来谈谈MySQL的临时表,到底是个什么东西,以及怎么样产生的的更多相关文章

  1. MySQL中的临时表到底什么是?

    Author:极客小俊 一个专注于web技术的80后 我不用拼过聪明人,我只需要拼过那些懒人 我就一定会超越大部分人! CSDN@极客小俊,原创文章, B站技术分享 B站视频 : Bilibili.c ...

  2. 谈谈MySQL数据表的类型(转)

    谈谈MySQL数据表的类型 通常意义上,数据库也就是数据的集合,具体到计算机上数据库可以是存储器上一些文件的集合或者一些内存数据的集合. 我们通常说的MySql数据库,sql server数据库等等其 ...

  3. 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景?

    在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种 ...

  4. 第36讲 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景

    在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种 ...

  5. 今天来学习一下MySQl的 临时表,变量,行转列,预处理的一些相关技术的使用!

    先来简单了解一下MySQL数据库有意思的简介 MySQL这个名字,起源不是很明确.一个比较有影响的说法是,基本指南和大量的库和工具带有前缀“my”已经有10年以上, 而且不管怎样,MySQL AB创始 ...

  6. 谈谈MySQL bin log的写入机制、以及线上的参数是如何配置的

    目录 一.binlog 的高速缓存 二.刷盘机制 三.推荐的策略 推荐阅读 问个问题吧!为什么你需要了解binlog的落盘机制呢? 我来回答一下: ​ 上一篇文章提到了生产环境中你可以使用binlog ...

  7. MYSQL 磁盘临时表和文件排序

    因为Memory引擎不支持BOLB和TEXT类型,所以,如果查询使用了BLOB或TEXT列并且需要使用隐式临时表,将不得不使用MyISAM磁盘临时表,即使只有几行数据也是如此. 这会导致严重的性能开销 ...

  8. 关于mysql的临时表并行的问题

    mysql的临时表并行是没问题的 以为临时表是基于会话的 1.因为在mysql里面每个会话的sessionid 不一样 2.其实就是会话级别的临时表  DB2里面有会话级别 全局级别的临时表,Orac ...

  9. 谈谈MySQL中的锁

    谈谈MySQL中的锁 锁的定义 ​ 在生活中锁的例子就非常多了,所以应该很容易理解锁的含义.在计算机领域,可以这样来概述,锁是计算机协调多个进行进程并发访问某一资源的机制. ​ 在数据库中,锁也是一个 ...

随机推荐

  1. elasticsearch 配置外网访问

    进入  config/ elasticsearch.ym 修改:network.host: 127.0.0.1 或者内网Ip 添加:http.host: 0.0.0.0

  2. 使用JS和PHP导出table表格

    把table表格的内容导出成excel 或者word等格式(简单容易不需要太多php) 导出需注意 1. 样式都在行间,导出excel表格会继承样式包括colspan.rowspan,非表格元素,样式 ...

  3. Linux学习笔记(三)Linux常用命令:链接命令和文件查找命令

    一.链接命令 ln -s [原文件] [目标文件] (link) -s意为创建软连接 硬链接和软连接 硬链接的特点: (1)拥有相同的 i 结点和block块,可以看作是同一个文件 (2)可以通过 i ...

  4. 封装Server类和Client类

    服务器端: EasyTcpServer.hpp #ifndef _EasyTcpServer_hpp_ #define _EasyTcpServer_hpp_ #ifdef _WIN32 #defin ...

  5. 异步函数Demo

    private static async Task<String> IssueClientRequestAsync(string serverName, string message) { ...

  6. Ubuntu系统--安装官方flash插件包的方法

    浏览器安装官方install_flash_player_npapi_linux.x86_64.tar.gz插件包的方法 第一步:下载安装包. adobe flash player的官方下载instal ...

  7. ndk学习之C语言基础复习----基本数据类型、数组

    关于NDK这个分类在N年前就已经创建了,但是一直木有系统的记录其学习过程,当然也没真正学会NDK的技术真谛,所以一直也是自己的一个遗憾,而如今对于Android程序员的要求也是越来越高,对于NDK也是 ...

  8. Python 获取 exe 的 icon 并且保存

    Python 获取 exe 的 icon 并且保存 参考链接:https://mail.python.org/pipermail/python-win32/2009-April/009078.html ...

  9. CSS样式设置小技巧

    1.水平居中设置 行内元素居中设置:如果被设置元素为文本.图片等行内元素时,水平居中是通过给父元素设置 text-align:center 来实现的.代码示例如下: HTML代码 <body&g ...

  10. [转]web.xml中servlet ,filter ,listener ,interceptor的作用与区别

    原文链接:https://blog.csdn.net/netdevgirl/article/details/51483273 一.概念: 1.servlet:servlet是一种运行服务器端的java ...