mysql临时表

临时表

MySQL 什么时候会使用内部临时表?

1、如果语句执行过程可以一边读数据,一边直接得到结果,是不需要额外内存的,否则就需要额外的内存,来保存中间结果;
2、join_buffer 是无序数组,sort_buffer 是有序数组,临时表是二维表结构;
3、如果执行逻辑需要用到二维表特性,就会优先考虑使用临时表。比如 union 需要用到唯一索引约束, group by 还需要用到另外一个字段来存累积计数。

  • 内存表

    指的是使用 Memory 引擎的表,建表语法是 create table … engine=memory。这种表的数据都保存在内存里,系统重启的时候会被清空,但是表结构还在。

  • 临时表

    可以使用各种引擎类型 。如果是使用 InnoDB 引擎或者 MyISAM 引擎的临时表,写数据的时候是写到磁盘上的。当然,临时表也可以使用 Memory 引擎。

临时表的特性

1、建表语法是 create temporary table …。
2、一个临时表只能被创建它的 session 访问,对其他线程不可见。session A 创建的临时表 t,对于 session B 就是不可见的。
3、临时表可以与普通表同名。
4、session A 内有同名的临时表和普通表的时候,show create 语句,以及增删改查语句访问的是临时表。
5、show tables 命令不显示临时表。
6、临时表只能被创建它的 session 访问,所以在这个 session 结束的时候,会自动删除临时表。使用数据库连接池,用完以后要手动删除,临时表

什么时候会使用内部临时表

1、union 执行流程

create table t1
(id int primary key,a  int,b  int,index(a)
);delimiter;;
create procedure idata()
begindeclare
i int;set
i=1;while
(i<=1000)doinsert into t1 values(i, i, i);set
i=i+1;
end while;
end;;
delimiter ;
call idata();(select 1000 as f)union(select id from t1 order by id desc limit 2);

执行流程是这样的:

1、创建一个内存临时表,这个临时表只有一个整型字段 f,并且 f 是主键字段。
2、执行第一个子查询,得到 1000 这个值,并存入临时表中。
3、执行第二个子查询:
3.1、拿到第一行 id=1000,试图插入临时表中。但由于 1000 这个值已经存在于临时表了,违反了唯一性约束,所以插入失败,然后继续执行;
3.2、取到第二行 id=999,插入临时表成功。
4、从临时表中按行取出数据,返回结果,并删除临时表,结果中包含两行数据分别是 1000 和 999。
union执行流程


union : 取这两个子查询结果的并集,重复的行只保留一行
union all : 取这两个子查询结果的并集,不去重

内存临时表起到了暂存数据的作用,而且计算过程还用上了临时表主键 id 的唯一性约束,实现了 union 的语义。如果把上面这个语句中的 union 改成 union all 的话,就没有了“去重”的语义。这样执行的时候,就依次执行子查询,得到的结果直接作为结果集的一部分,发给客户端。因此也就不需要临时表了。

2、group by 执行流程

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

执行流程:

1、创建内存临时表,表里有两个字段 m 和 c,主键是 m;
2、扫描表 t1 的索引 a,依次取出叶子节点上的 id 值,计算 id%10 的结果,记为 x;

如果临时表中没有主键为 x 的行,就插入一个记录 (x,1);
如果表中有主键为 x 的行,就将 x 这一行的 c 值加 1;
3、遍历完成后,再根据字段 m 做排序,得到结果集返回给客户端。
在这里插入图片描述

如果不需要对结果进行排序,那可以在 SQL 语句末尾增加 order by null,这样就跳过了最后排序的阶段,直接从临时表中取数据返回

select id%10 as m, count(*) as c from t1 group by m order by null;
  • 这个例子里由于临时表只有 10 行,内存可以放得下,因此全程只使用了内存临时表。但是,内存临时表的大小是有限制的,参数 tmp_table_size 就是控制这个内存大小的,默认是 16M。
  • 如果内存临时表大小不够存下,这时候就会把内存临时表转成磁盘临时表,磁盘临时表默认使用的引擎是 InnoDB

  • group by 优化方法 – 索引

不论是使用内存临时表还是磁盘临时表,group by 逻辑都需要构造一个带唯一索引的表,执行代价都是比较高的
执行 group by 语句为什么需要临时表?
group by 的语义逻辑,是统计不同的值出现的个数。但是,由于每一行的 id%100 的结果是无序的,所以我们就需要有一个临时表,来记录并统计结果。


在这里插入图片描述

如果可以确保输入的数据是有序的,那么计算 group by 的时候,就只需要从左到右,顺序扫描,依次累加。也就是下面这个过程:如果可以确保输入的数据是有序的,那么计算 group by 的时候,就只需要从左到右,顺序扫描,依次累加。也就是下面这个过程:
当碰到第一个 1 的时候,已经知道累积了 X 个 0,结果集里的第一行就是 (0,X);
当碰到第一个 2 的时候,已经知道累积了 Y 个 1,结果集里的第二行就是 (1,Y);
按照这个逻辑执行的话,扫描到整个输入的数据结束,就可以拿到 group by 的结果,不需要临时表,也不需要再额外排序。

在 MySQL 5.7 版本支持了 generated column 机制,用来实现列数据的关联更新。你可以用下面的方法创建一个列 z,然后在 z 列上创建一个索引(如果是 MySQL 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;
  • group by 优化方法 – 直接排序
    如果碰上不适合创建索引的场景,还是要老老实实做排序的


    在 group by 语句中加入 SQL_BIG_RESULT 这个提示(hint),就可以告诉优化器:这个语句涉及的数据量很大,请直接用磁盘临时表。


    MySQL 的优化器一看,磁盘临时表是 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 做排序(如果 sort_buffer 内存不够用,就会利用磁盘临时文件辅助排序);
    4、排序完成后,就得到了一个有序数组。

    后,对 sort_buffer 的字段 m 做排序(如果 sort_buffer 内存不够用,就会利用磁盘临时文件辅助排序);
    4、排序完成后,就得到了一个有序数组。
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/10768.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

维修西门子PC677B工控机 IPC677D IPC677C IPC577C TP1500 TP1200

SIMATIC Panel PC 677B 主要亮点是&#xff1a; 得益于最新的英特尔技术&#xff0c;高系统性能可满足要求苛刻的可视化、计算和控制任务 英特尔 移动处理器&#xff1a;Core 2 ​​Duo&#xff08;双核&#xff09;或 Celeron M DDR2 667 内存高达 4 GB RAM PCI Express (PCI…

中国电子学会(CEIT)2022年12月真题C语言软件编程等级考试三级(含详细解析答案)

中国电子学会(CEIT)考评中心历届真题(含解析答案) C语言软件编程等级考试一级 2022年12月 编程题五道 总分:100分一、鸡兔同笼(20分) 一个笼子里面关了鸡和兔子(鸡有2只脚,兔子有4只脚,没有例外)。已经知道了笼子里面脚的总数a,问笼子里面至少有多少只动物,至…

重生奇迹mu战士攻略有哪些

1、生命之光&#xff1a;PK前起手式&#xff0c;增加血上限。 2、雷霆裂闪&#xff1a;眩晕住对手&#xff0c;战士PK战士第一技能&#xff0c;雷霆裂闪是否使用好关系到胜负。 3、霹雳回旋斩&#xff1a;雷霆裂闪后可以选择用霹雳回旋斩跑出一定范围(因为对手下一招没出意外…

Vue的diff算法

Vue.js 的 diff 算法是其性能优化的关键部分&#xff0c;它用于比较新旧虚拟 DOM 树并计算出最小的变更集&#xff0c;以便将这些变更应用到真实的 DOM 上。这种比较和计算的过程被称为“diff”或“差异化”。 以下是 Vue.js diff 算法的一些核心特性和概念&#xff1a; 基于…

指针的奥秘(四):回调函数+qsort使用+qsort模拟实现冒泡排序

指针 一.回调函数是什么&#xff1f;二.qsort函数使用1.qsort介绍2.qsort排序整型数据3.qsort排序结构体数据1.通过结构体中的整形成员排序2.通过结构体中的字符串成员排序 三.qsort模拟实现冒泡排序 一.回调函数是什么&#xff1f; 回调函数就是一个通过函数指针调用的函数。 …

You Only Cache Once:YOCO 基于Decoder-Decoder 的一个新的大语言模型架构

这是微软再5月刚刚发布的一篇论文提出了一种解码器-解码器架构YOCO&#xff0c;因为只缓存一次KV对&#xff0c;所以可以大量的节省内存。 以前的模型都是通过缓存先前计算的键/值向量&#xff0c;可以在当前生成步骤中重用它们。键值(KV)缓存避免了对每个词元再次编码的过程&…

C/C++常用的编译器分类

1.GCC家族 GNU GCC、GNU C、Mingw、Dev-C(Mingw)、Cygwin、DJGPP gcc 原名GNU C Collection,后因支持多种编程语言&#xff0c;改名为GNU Compiler Collection&#xff0c;是大多数类Unix&#xff08;如Linux)的标准编译器&#xff0c;且适用于Windows(借助其他移植项目实现&…

Zookeeper笔记,MIT6.824

ZooKeeper旨在提供一个简单和高性能的内核&#xff0c;使得客户端可以构建更复杂的协调原语。 它将组消息传递、共享寄存器和分布式锁等服务整合到一个重新分配的、集中的服务中。 由ZooKeeper暴露出来的接口在共享寄存器方面具有无等待的特性&#xff0c;使用类似于分布式文件…

.NET应用程序中实现安全性的最佳实践

在.NET应用程序中实现安全性是一个复杂但至关重要的任务。 以下是一些关于身份验证、授权、加密和数据保护的最佳实践&#xff1a; 一、身份验证 使用强密码策略&#xff1a;确保用户创建复杂的密码&#xff0c;并定期更改。多因素身份验证&#xff1a;除了用户名和密码外&a…

[力扣题解]1005. K 次取反后最大化的数组和

题目&#xff1a;1005. K 次取反后最大化的数组和 思路 贪心法&#xff1b; 用绝对值大小排序&#xff0c;自己写一个比较函数&#xff0c; static bool compare(int a, int b) {return abs(a) > abs(b); }注意这样写出来是降序排列&#xff1b; 2次贪心&#xff1a; &a…

全学科知网普刊征稿中!即日提交,月内即可见刊!

在当前的学术环境下&#xff0c;论文发表的压力日益增大。当您需要评职称、申请学位、结项课题或完成其他有期限的学术要求时&#xff0c;快速发表普刊能够确保您及时满足这些需求&#xff0c;提升您的职业竞争力&#xff0c;为您的职业发展需求打下坚实基础。 我处普刊现积极…

我的全新官网

科技语者-探索未来的语言和沟通 (chgskj.cn) 另外我还开放了一个网站科技语者-介绍页 (null.fit)

无锡哲讯在SAP实施方面的有哪些优势?

无锡哲讯在SAP实施领域展现出的专业性、技术实力和客户服务等方面的优势&#xff0c;使其成为众多企业在SAP相关项目中的优选合作伙伴。下面就从行业经验、解决方案、技术实力、服务范围和客户口碑几大方面介绍无锡哲讯在SAP实施领域的优势&#xff1a; 丰富的行业经验&#xf…

iOS 音量键拍照(延时拍照)

写在前面 下面有两种方法可以实现&#xff0c;一种简单&#xff0c;一种复杂&#xff0c;简单的方法曾经遇到过无法实现的问题&#xff0c;目前不确定为什么。 这是复杂实现的demo&#xff0c;使用很简单&#xff0c;就不做文字解释了 一. 思路 首先需要监听音量键的点击&a…

Java反射(含静态代理模式、动态代理模式、类加载器以及JavaBean相关内容)

目录 1、什么是反射 2、Class类 3、通过Class类取得类信息/调用属性或方法 4、静态代理和动态代理 5.类加载器原理分析 6、JavaBean 1、什么是反射 Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息&#xff0c;从而操作类或对象的属性和方法。本质是JVM得…

速盾:高防服务器和高防cdn的区别

高防服务器和高防CDN是两种常用的网络安全解决方案&#xff0c;用于保护网站免受恶意攻击和DDoS攻击的影响。虽然它们都有类似的目标&#xff0c;但在保护机制、性能表现和适用场景等方面有一些区别。 首先&#xff0c;高防服务器是一种物理硬件设备&#xff0c;通常是一台具备…

java基础之面向对象的思想

一、面向对象和面向过程的编程思想对比 面向过程&#xff1a;是一种以过程为中心的编程思想&#xff0c;实现功能的每一步&#xff0c;都是自己实现的&#xff08;自己干活&#xff09;。 面向对象&#xff1a;是一种以对象为中心的编程思想&#xff0c;通过指挥对象实现具体的…

智慧生活:AI工具如何改变我们的工作与生活

文章目录 &#x1f4d1;前言一、常用AI工具&#xff1a;便利与高效的结合1.1 语音助手1.2 智能推荐系统1.3 自然语言处理工具 二、创新AI应用&#xff1a;不断突破与发展2.1 医疗诊断AI2.2 智能家居2.3 无人驾驶技术 三、AI工具在人们生活中的应用和影响3.1 生活方式的变化3.2 …

docker和docker-compose常用指令

在 Docker 中&#xff0c;有许多常用的命令来管理容器、镜像、网络和卷。这些命令对于修复错误、更新、重建和重新运行应用尤为重要。下面是一些最常用的 Docker 命令和它们的基本用途&#xff1a; ### 1. 容器管理 - **启动容器**: bash docker start <容器ID或名称&g…

Stream流入门和创建方式

Java 8引入了Stream API&#xff0c;它提供了一种新的数据处理方式&#xff0c;使得集合和数组的处理更加灵活、高效。Stream API不是直接操作数据结构中的元素&#xff0c;而是对数据源创建一个数据流&#xff0c;通过声明式的方式对数据进行操作&#xff0c;如过滤、映射、排…