来谈谈MySQL的临时表,到底是个什么东西,以及怎么样产生的
介绍临时表之前,我们首先来看这么一句语句:
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的临时表,到底是个什么东西,以及怎么样产生的的更多相关文章
- MySQL中的临时表到底什么是?
Author:极客小俊 一个专注于web技术的80后 我不用拼过聪明人,我只需要拼过那些懒人 我就一定会超越大部分人! CSDN@极客小俊,原创文章, B站技术分享 B站视频 : Bilibili.c ...
- 谈谈MySQL数据表的类型(转)
谈谈MySQL数据表的类型 通常意义上,数据库也就是数据的集合,具体到计算机上数据库可以是存储器上一些文件的集合或者一些内存数据的集合. 我们通常说的MySql数据库,sql server数据库等等其 ...
- 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景?
在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种 ...
- 第36讲 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景
在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种 ...
- 今天来学习一下MySQl的 临时表,变量,行转列,预处理的一些相关技术的使用!
先来简单了解一下MySQL数据库有意思的简介 MySQL这个名字,起源不是很明确.一个比较有影响的说法是,基本指南和大量的库和工具带有前缀“my”已经有10年以上, 而且不管怎样,MySQL AB创始 ...
- 谈谈MySQL bin log的写入机制、以及线上的参数是如何配置的
目录 一.binlog 的高速缓存 二.刷盘机制 三.推荐的策略 推荐阅读 问个问题吧!为什么你需要了解binlog的落盘机制呢? 我来回答一下: 上一篇文章提到了生产环境中你可以使用binlog ...
- MYSQL 磁盘临时表和文件排序
因为Memory引擎不支持BOLB和TEXT类型,所以,如果查询使用了BLOB或TEXT列并且需要使用隐式临时表,将不得不使用MyISAM磁盘临时表,即使只有几行数据也是如此. 这会导致严重的性能开销 ...
- 关于mysql的临时表并行的问题
mysql的临时表并行是没问题的 以为临时表是基于会话的 1.因为在mysql里面每个会话的sessionid 不一样 2.其实就是会话级别的临时表 DB2里面有会话级别 全局级别的临时表,Orac ...
- 谈谈MySQL中的锁
谈谈MySQL中的锁 锁的定义 在生活中锁的例子就非常多了,所以应该很容易理解锁的含义.在计算机领域,可以这样来概述,锁是计算机协调多个进行进程并发访问某一资源的机制. 在数据库中,锁也是一个 ...
随机推荐
- 如何确定asp.net请求生命周期的当前处理事件
1 首先在全局应用程序里面添加如下代码 using System; using System.Collections.Generic; using System.Linq; using System. ...
- python实现数据的压缩与归档
楔子 尽管现代计算机系统的存储能力日益增长,但生成数据的增长是永无休止的. 无损(lossless)压缩算法以压缩或解压缩数据花费的时间来换取存储数据所需要的空间,以弥补存储能力的不足. Python ...
- Comparator分组测试
import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.u ...
- 如何给mysql数据库添加一个用户
首先以root身份登录到MySQL服务器中. $ mysql -u root -p 当验证提示出现的时候,输入MySQL的root帐号的密码. 创建一个MySQL用户 使用如下命令创建一个用户名和密码 ...
- 用 Spark 处理复杂数据类型(Array、Map、JSON字符串等)
split 对列表进行切割,然后生产新的列表 from pyspark.sql.functions import split# 对 key列按照 0-9之间的数字进行风格 重新命名为 s df.se ...
- Appium&Java自动化实现移动端几种典型动作
一.Appium4.0 Pinch&Zoom /* * @FileName Pinch_Zoom: Pinch_Zoom * @author davieyang * @create 2018- ...
- python .pth 文件 和 site 模块
python .pth 文件 和 site 模块 .pth 文件 该文件位于 python 的 /Lib/site-packages 目录下,可以有多个,在 .pth 文件中可以把其它目录添加到 sy ...
- mysql锁定单个表的方法
mysql锁定单个表的方法mysql>lock table userstat read;mysql>unlock tables; 本文来自ChinaUnix博客,如果查看原文请点:http ...
- 状压dp做题笔记
CodeChef Factorial to Square (分块决策) Description 给定一个n,要求在[1,n]中删除一些数,并使剩下的数的乘积是一个完全平方数,同时要求乘积最大,求删除方 ...
- Codeforces Round #586 (Div. 1 + Div. 2) A. Cards
链接: https://codeforces.com/contest/1220/problem/A 题意: When Serezha was three years old, he was given ...