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,一经查实,立即删除!

相关文章

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

1、生命之光&#xff1a;PK前起手式&#xff0c;增加血上限。 2、雷霆裂闪&#xff1a;眩晕住对手&#xff0c;战士PK战士第一技能&#xff0c;雷霆裂闪是否使用好关系到胜负。 3、霹雳回旋斩&#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)缓存避免了对每个词元再次编码的过程&…

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

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

我的全新官网

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

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

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

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 …

搭建本地yum仓库

步骤 找个地方存你的rpm包 #我创建了一个rpm文件夹存放我的rpm包 makdir -p /opt/repo/rpmcreaterepo 这个很重要&#xff0c;一定要安装 # 我的能连外网&#xff0c;所以直接yum安装&#xff0c;你的自己想办法 yum install createrepo -y创建repodata 安装了createrepo后…

SOA构架介绍

1.SOA定义 SOA面向服务的架构是一种计算机环境设计、开发、部署和管理离散模型的方法&#xff0c;SOA中所有的功能都被定义成立独立的服务&#xff0c;所有的服务通过总线&#xff08;ESB)或者流程管理连接。这种松耦合的结构使得服务器在交互的过程中无需考虑双方内部细节&am…

RocketMQ(一)

作用 1. 限流削峰 2. 异步解耦 组成 Producer&#xff1a;消息的发送者&#xff0c;生产者&#xff1b;举例&#xff1a;发件人 Consumer&#xff1a;消息接收者&#xff0c;消费者&#xff1b;举例&#xff1a;收件人 Broker&#xff1a;暂存和传输消息的通道&#xff1…

矩阵稀疏扫描 - 矩阵

系列文章目录 文章目录 系列文章目录前言一、题目描述二、输入描述三、输出描述四、Java代码五、测试用例提示 前言 本人最近再练习算法&#xff0c;所以会发布一些解题思路&#xff0c;希望大家多指教 一、题目描述 如果矩阵中的许多系数都为零&#xff0c;那么该矩阵就是稀…

Rust编程语言的特点及其适合做什么

Rust编程语言的特点 Rust是一门系统级编程语言&#xff0c;它有如下特点。 1. 类C的语言语法 Rust的具体语法和C/C类似&#xff0c;都是由花括号限定代码块&#xff0c;还有一样的控制流关键字&#xff0c;例如if、else、while和for。然而&#xff0c;也并非所有的C或者C关键…

Scratch四级:第07讲 编程数学02

第07讲 编程数学02 教练&#xff1a;老马的程序人生 微信&#xff1a;ProgrammingAssistant 博客&#xff1a;https://lsgogroup.blog.csdn.net/ 讲课目录 常考的数学问题项目制作&#xff1a;“求最大公约数”项目制作&#xff1a;“求最小公倍数”项目制作&#xff1a;“早餐…

RAG讲解

现有的LLM已经具备了理解、生成、逻辑和记忆能力&#xff0c;RAG(Retrieval Augmented Generation)则是为其套上外挂&#xff0c;使LLM能够访问训练数据来源之外的权威知识库&#xff0c;并生成领域特定的内容&#xff0c;而无须重新训练模型。 RAG的优势 经济高效&#xff1a…

Meilisearch使用过程趟过的坑

Elasticsearch 做为老牌搜索引擎&#xff0c;功能基本满足&#xff0c;但复杂&#xff0c;重量级&#xff0c;适合大数据量。 MeiliSearch 设计目标针对数据在 500GB 左右的搜索需求&#xff0c;极快&#xff0c;单文件&#xff0c;超轻量。 所以&#xff0c;对于中小型项目来说…

opencompass实践

参考教程 https://github.com/InternLM/Tutorial/blob/camp2/opencompass/readme.md 下载opencompass&#xff0c;配置必要的环境之后&#xff0c;解压下载的数据集 cp /share/temp/datasets/OpenCompassData-core-20231110.zip /root/opencompass/ unzip OpenCompassData-co…

如何远程操作服务器中的Python编译器并将运行结果返回到Pycharm

文章目录 一、前期准备1. 检查IDE版本是否支持2. 服务器需要开通SSH服务 二、Pycharm本地链接服务器测试1. 配置服务器python解释器 三、使用内网穿透实现异地链接服务器开发1. 服务器安装Cpolar2. 创建远程连接公网地址 四、使用固定TCP地址远程开发 本文主要介绍如何使用Pych…

RPA正常跑,cmd输入cookies跑不出来,如何解决??

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

SQL-递归查询

运行环境&#xff1a; Mysql8以上&#xff0c;递归查询功能在8以上版本被正式引入 一、SQL递归查询的概念 递归指的是通过调用函数或过程或自身来解决问题的方法&#xff0c;常用于一些具有规律性循环的操作。SQL递归查询是基于一组初始数据&#xff0c;通过递归查询&#xf…