37 | 什么时候会使用内部临时表?(思考题未完)

第 16第 34 sort buffer、内存临时表join buffer。存放中间数据,排序的时候用到了 sort buffer,在使用 join 语句的时候用到了 join buffer。

一、union 执行流程

查询结果并集(select 1000 as  f) union (select id from t1 order by id desc limit 2);

图 1 union 语句 explain 结果  

第二行 key=PRIMARY用了索引 id

第三行Extra :结果集union用临时表 (Using temporary)。

1.  创建一个内存临时表,只有整型字段 f,主键。

2.  第一个子查询,得到 1000 这个值,存入临时表中。

3. 执行第二个子查询:拿到 id=1000,违反了唯一性约束,插入失败;取第二行 id=999,插入成功。

包含 1000 和 999。

图 2 union 执行流程

union 改成 union all 的话,不去重”的语义。依次子查询。不需临时表。

图 3 union all 的 explain 结果

Using index,表示只使用了覆盖索引,没用临时表。

二、group by 执行流程

select id%10 as  m, count(*) as c from t1 group by m;

t1 数据,按id%10 分组统计,按m 结果排序后输出

[endif]不支持该协议取消重新上传图 4 group by 的 explain 结果  

Using index,覆盖索引 a,不需回表;Using temporary临时表;Using filesort,需排序

1.  创建内存临时表,字段 m (主键)和 c

2.  [扫描 t1 的索引 a,依次取出叶子节点上id 值,计算 id%10 的结果,记为 x;

临时表中没有主键 x 行插入(x,1);有,这一行的 c 值加 1

3.  遍历完,根据m排序返回

图 5 group by 执行流程

内存临时表的排序,在第 17 篇文章

图 6 内存临时表排序流程  (虚线框内)
图 7 group by 执行结果

不需排序,末尾增加 order by null:select id%10 as  m, count(*) as c from t1 group by m order by null;

图 8 group + order by null 的结果(内存临时表)

 t1 中的 id 从 1 开始,第一行是 id=1,临时表只有 10 行,内存放得下,tmp_table_size 控内存大小,默认16M。

set  tmp_table_size=1024;//最大 1024 字节

select id%100 as  m, count(*) as c from t1 group by m order by null limit 10;

id % 100,返回结果 100 行不够存,转成磁盘临时表数据量大,查询磁盘临时表会占用大量磁盘空间

图 9 group + order by null 的结果(磁盘临时表)  

三、group by 优化方法-- 索引

group by 需要唯一索引,执行代价高。数据量大,group by 慢:统计不同值出现个数。 id%100 结果是无序,需个临时表记录并统计结果。

图 10 group by 算法优化 - 有序输入

数据有序,group by 的时候,只需左到右,顺序扫描不需临时表和排序

碰到第一个1 时,已知累积 X 个 0,结果集第一行(0,X);

碰到第一个 2 时,已知累积Y 个 1,结果集第二行(1,Y);

InnoDB 索引,满足输入有序的条件。MySQL 5.7 版本支持generated column 实现列数据关联更新。创建列 z, z 上创建索引(5.6 之前,可以创建普通列和索引解决)。

alter table t1  add column z int generated always as(id % 100), add index(z);

索引 z 上有序, group by 改成:select z,  count(*) as c from t1 group by z;

Extra 看到,不再需要临时表和排序

图 11 group by 优化的 explain 结果  

四、group by 优化方法-- 直接排序

不适合建索引场景,怎么优化呢?放到临时表数据量大,直接走磁盘临时表

group by 加SQL_BIG_RESULT 提示(hint)优化器:量大用磁盘临时表。

磁盘临时表B+ 树存储,存储效率不如数组高。直接用数组存

select  SQL_BIG_RESULT id%100 as m, count(*) as c from t1 group by m;

1.  初始化 sort_buffer,整型字段 m;

2.  扫描 t1 索引 a,依次取出 id 值, 将 id%100 值存入 sort_buffer 中;

3. 扫描后,对 sort_buffer 字段 m 排序(内存不够,用磁盘临时文件辅助排序);

4.  排序完成后,得有序数组(不同值,每个值出现次数)


图 12 使用 SQL_BIG_RESULT 的执行流程图
图 13 使用 SQL_BIG_RESULT 的 explain 结果

Extra :没用临时表,直接用排序算法

什么时候用内部临时表

1. 可边读数据,边得结果,不额外内存,否则就需额外内存,保存中间结果;

2.  用到二维表特性,用临时表。union用到唯一索引约束group by 用另外一个字段存累积计数

join_buffer 是无序数组,sort_buffer 是有序数组,临时表二维表结构;

小结

1.  group by 没排序要求,后面加 order by null

2.  尽量让 group by 用表索引,确认方法 explain 结果里没有 Using temporary 和 Using filesort;

3.  group by 统计数据量不大,用内存临时表;适当调大tmp_table_size,避免用磁盘临时表

4.  数据量大,用SQL_BIG_RESULT 提示,告诉优化器用排序算法得 group by 结果

思考题

图 8 和图 9 都是 order by null,图 8 ,0 最后一行,图 9 ,0第一行?

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容