MySQL什么时候会使用内部临时表?
1.union执行过程
首先我们创建一个表t1
create table t1(id int primary key, a int, b int, index(a));
delimiter ;;
create procedure idata()
begin
declare i int;
set i=1;
while(i<=1000)do
insert into t1 values(i, i, i);
set i=i+1;
end while;
end;;
delimiter ;
call idata();
然后我们执行一下这条语句
explain select 1000 as f union (select id from t1 order by id desc limit 2)
首先说下union的语义,union的语义是取两个结果的并集,重复的保留一行,然后我们来看下explain的结果,第二行的key=PRIMARY,说明用到了主键索引。
第三行的Extra的Using temporary说明用到了临时表
下面我们看下这条语句的执行流程:
1.创建一个临时表,只有f一个字段,且为主键
2.将1000这个数据插入临时表
3.子查询中步骤:
1.插入1000进入临时表,因为主键冲突,插入失败
2.插入第二行900,插入成功
4.将临时表数据作为结果返回,并删除临时表
这个过程的流程图如下:
如果我们把union改成union all,就不需要使用临时表了,因为union all是重复的也保留,
大家可以看到extra这一列已经没有了Using temporary
explain select 1000 as f union all (select id from t1 order by id desc limit 2)
2.group by执行过程
我们来看下面这条语句:
explain select id%10 as m, count(*) as c from t1 group by m;
可以看到explain结果
Using index(使用到了覆盖索引a,不需要回表); Using temporary(用到了临时表); Using filesort(对数据进行了排序)
这条语句的意思是将id%10进行分组统计,并按照m进行排序
执行流程如下:
1.创建临时表,增加m,c字段,m是主键
2.计算id%10的结果记为x
3.如果临时表里面没有主键为x的行,则插入(x,1),如果有的话,就将该行的c值加1
4.遍历完成后,按照m字段排序返回结果给客户端
流程图如下
接下来我们看下这条语句的执行结果
explain select id%10 as m, count(*) as c from t1 group by m
其实,如果我们不需要对查询结果进行排序,我们可以加一个order by null
我们执行一下这条语句
explain select id%10 as m, count(*) as c from t1 group by m order by null
可以看到这里没有进行排序,由于扫描是从表t的id是从1开始的,所以第一行是1
如果我们执行下列语句,会发生什么呢?
我们上面说的临时表,其实是内存临时表,如果我们把内存临时表的容量改的比我们要查询的数据的容量小,那么就会使用到磁盘临时表,磁盘临时表的默认引擎是innodb
et tmp_table_size=1024;
select id%100 as m, count(*) as c from t1 group by m order by null limit 10
group by 优化方法--直接排序
其实在上面的关于从内存临时表转化成磁盘临时表是很浪费时间的,也就是说mysql,在执行过程中发现空间不够了,在转成磁盘临时表,但是如果我们直接告诉mysql,我要查询的数据很大,那么mysql优化器就会想到,既然你告诉我数据很大,那么我就直接用sort_buffer进行排序,如果sort_buffer内存不够大,会用到磁盘临时表辅助排序。
select SQL_BIG_RESULT id%100 as m, count(*) as c from t1 group by m;
小结一下:
1.如果我们不需要对统计结果进行排序,可以加上order by null省去排序流程。
2.尽量让排序过程用上内存临时表,可以通过适当调大tmp_table_size的值来避免用到磁盘临时表。
3.如果数据量实在太大,使用SQL_BIG_RESULT告诉优化器,直接使用排序算法。
MySQL什么时候会使用内部临时表?的更多相关文章
- MySQL · 特性分析 · 内部临时表
http://mysql.taobao.org/monthly/2016/06/07/#rd MySQL中的两种临时表 外部临时表 通过CREATE TEMPORARY TABLE 创建的临时表,这种 ...
- MySQL -- 内部临时表
本文转载自MySQL -- 内部临时表 UNION UNION语义:取两个子查询结果的并集,重复的行只保留一行 表初始化 CREATE TABLE t1(id INT PRIMARY KEY, a I ...
- MySQL安装出现“不是内部或外部命令,也不是可执行程序”等一系列问题的解决方案
MySQL安装出现“不是内部或外部命令,也不是可执行程序” 一.这是应该是环境变量处问题了,设置如下: 1)右击我的电脑选择“属性”,找到“高级系统设置” 2)在系统属性下,选择“高级”中的“环境变量 ...
- Mysql学习笔记(十一)临时表+视图
学习内容: 临时表和视图的基本操作... 临时表与视图的使用范围... 1.临时表 临时表:临时表,想必大家都知道这个概念的存在...但是我们什么时候应该使用到临时表呢?当一个数据库存在着大量的数 ...
- MySQL如何删除#sql开头的临时表
1. 现象 巡检时发现服务器磁盘空间不足,通过查看大文件进行筛选是发现有几个#sql开头的文件,且存在超过100G及10G以上的文件. 2. 原因 如果MySQL在一个 ALTER TABLE操作( ...
- mysql优化: 内存表和临时表
由于直接使用临时表来创建中间表,其速度不如人意,因而就有了把临时表建成内存表的想法.但内存表和临时表的区别且并不熟悉,需要查找资料了.一开始以为临时表是创建后存在,当连接断开时临时表就会被删除,即临时 ...
- mysql安装后不是内部或外部命令解决
在环境变量中配置mysql的bin 怎么找到bin目录,在管理工具,服务,常规选项卡下找到 双击mysql后,常规选项卡下的路径就是bin的路径,然后把该路径配置到环境变量中,即可,然后net sta ...
- IIS+PHP+Mysql 返回500,服务器内部资源问题
这个错误困扰了我好久.... 尝试了好多方法都不管用,最后突然发现我的代码是: <?php $link=mysql_connect("localhost","xxx ...
- mysql 分组查询的结果当成临时表 在求最大值
select avg(data1) as a from temp WHERE YEAR(mdate)= 2018 and MONTH(mdate)=03 and day(mdate)=25 GROUP ...
随机推荐
- C06 变量和存储类型
目录 全局变量 局部变量 存储类型 全局变量和局部变量 变量的作用域 作用域:某些事物起作用或有效的区域. 变量的使用范围称为变量的作用域. 变量的作用域决定了变量的可操作性和有效性. C语言变量的作 ...
- 使用gcc -g编译,gdb调试时仍然存在“no debug symbols found”的错误
今天为调试一段代码,使用gcc将程序用-g选项重新编译.但是使用gdb进行debug时,仍然出现“no debug symbols found”的错误.仔细检查了一下Makefile,原来后面定义的连 ...
- POI读word doc 03 文件的两种方法
Apache poi的hwpf模块是专门用来对word doc文件进行读写操作的.在hwpf里面我们使用HWPFDocument来表示一个word doc文档.在HWPFDocument里面有这么几个 ...
- please upgrade your plan to create a new private reposiory
请升级你的计划来创建一个新的私人仓库 提交仓库到github,要公开,除非买他们服务,所以把勾去掉就好了keep this code private
- javaEE(8)_EL表达式语言
一.EL表达式简介 EL全名为Expression Language.EL主要作用: 1>获取数据: •EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域中检索java对象. ...
- 74个Swift标准库函数
74个Swift标准库函数 本文译自 Swift Standard Library: Documented and undocumented built-in functions in the Swi ...
- 【简●解】 LG P2730 【魔板 Magic Squares】
LG P2730 [魔板 Magic Squares] [题目背景] 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 ...
- fopen()和socket()的内在联系
int portone=socket(AF_INET,SOCK_STREAM, 0); printf("portone=%d",portone); printf("ope ...
- UVA-1220-Party at Hali-Bula && UVA-1218-Perfect Service(树形DP)
UVA-1220-Party at Hali-Bula 题意: 一个公司员工要举行聚会,要求任意一个人不能和他的直接上司同时到场,一个员工只有一个支系上司,现在求最多有多少人到场,并且方案是否唯一(紫 ...
- Mac OS 终端强化美化:iterm2 + zsh + oh~my~zsh 设置教程
为了获得更好的排版效果,文章改用markdown撰写,故重发一次. 前言 mac自带的terminal终端没有文件名高亮等功能,而且界面不是很好看,故今晚学舍友折腾了终端,可以让自己使用起来更加方便, ...