关于mysql建立临时表的问题(新手入门)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于mysql建立临时表的问题(新手入门)相关的知识,希望对你有一定的参考价值。

我网上找了一些资料关于MYSQL建立临时表的,我是刚学习MYSQL所以我想问一下他的建立使用等问题。
比如我在网站程序里使用了一个连接,来连接到数据库,再传入SQL语句来得到返回结果。
我想的问的是如果我要建立临时表是不是在我的传入语句里加一条建立临时表的SQL语句?
如果我查询的是一个临时表里的数据,那么查完后我就会关闭连接,那么我第二次查询的时候那是不是有得再建?(因为我一次不提完数据)
那不是很浪费?
不知道我的想法是错的不?

知道的能把这个使用流程说下吗?麻烦了
不是 说我 临时表我断开连接就没了吗?
比如分页我不可能把所有数据都读去出来吧?

1、临时表再断开于mysql的连接后系统会自动删除临时表中的数据,但是这只限于用下面语句建立的表:
1)定义字段
CREATE TEMPORARY TABLE tmp_table (
name VARCHAR(10) NOT NULL,
value INTEGER NOT NULL
)
2)直接将查询结果导入临时表
CREATE TEMPORARY TABLE tmp_table SELECT * FROM table_name

2、另外mysql也允许你在内存中直接创建临时表,因为是在内存中所有速度会很快,语法如下:
CREATE TEMPORARY TABLE tmp_table (
name VARCHAR(10) NOT NULL,
value INTEGER NOT NULL
) TYPE = HEAP

3、从上面的分析可以看出临时表的数据是会被清空的,你断开了连接就会被自动清空,但是你程序中不可能每发行一次sql就连接一次数据库吧(如果是这样的话,那就会出现你担心的问题,如果不是就没有问题),因为只有断开数据库连接才会被清空数据,在一个数据库连接里面发行多次sql的话系统是不会自动清空临时表数据的。

---
以上,希望对你有所帮助。
参考技术A mysql的临时表和sql server不太一样。没有create @table()这样写法。一般的复杂query,如果mysql认为要用临时表会自动在临时目录下创建像#234.frm这样的文件。如果你要为加快查询手工创建临时表,一般都是先truncate 清空。再向其中insert 数据,最后才是select。 参考技术B

提到MySQL临时表,我们都很熟悉了,一般来说,分为两类:

1. MySQL 临时表引擎,名字叫做 Memory。比如

create table tmp1(id int, str1 varchar(100) ) engine = memory;

由参数max_heap_table_size 来控制,超过报错。

2. 非临时表的引擎,这里又分为两类:

    用户自定义的临时表,比如:

    create temporary table (id int, str1 varchar(100) );

    SQL执行过程中产生的内部临时表,比如:UNION , 聚合类ORDER BY,派生表,大对象字段的查询,子查询或者半连接的固化等等场景。

    那么这两种临时表的计数器通常用 show global status like '%tmp_%tables%' 来查看。比如

    mysql> show status like '%tmp_%tables%';``+-------------------------+-------+``| Variable_name           | Value |``+-------------------------+-------+``| Created_tmp_disk_tables | 0     |``| Created_tmp_tables      | 0     |``+-------------------------+-------+``2 rows in set (0.00 sec)

    以上结果分别代表,只创建磁盘上的临时表计数以及临时表的总计数。这两个计数器由参数 tmp_table_size 和 max_heap_table_size 两个取最小值来控制。

    那在 MySQL 5.7 之前,这个 SQL 运行中产生的临时表是 MYISAM,而且只能是 MYISAM。那 MySQL 从 5.7 开始提供了参数 Internal_tmp_mem_storage_engine 来定义内部的临时表引擎,可选值为 MYISAM 和 INNODB 。当然这里我们选择 INNODB 。并且把内部的临时表默认保存在临时表空间 ibtmp1 (可以用参数 innodb_temp_data_file_path 设置大小以及步长等)下。当然这里我们得控制下 ibtmp1 的大小,要不然一个烂SQL就把磁盘整爆了。

    但是MySQL 5.7 之前都没有解决如下问题:

    VARCHAR的变长存储。那就是如果临时表的字段定义是 VARCHAR(200),那么映射到内存里处理的字段变为CHAR(200)。假设 VARCHAR(200) 就存里一个字符 "Y", 那岂不是很大的浪费。

    大对象的默认磁盘存储,比如 TEXT,BLOB, JSON等,不管里面存放了啥,直接转化为磁盘存储。

    MySQL 8.0 开始,专门实现了一个临时表的引擎 TempTable , 解决了 VARCHAR字段的边长存储以及大对象的内存存储。由变量 interal_tmp_mem_storage_engine来控制,可选值为 TempTable(默认)和 Memory;新引擎的大小由参数temp_table_max_ram 来控制,默认为1G。超过了则存储在磁盘上(ibtmp1)。并且计数器由性能字典的表 memory_summary_global_by_event_name 来存储。

    mysql> SELECT * FROM performance_schema. memory_summary_global_by_event_name WHERE event_name like '%temptable%'G*************************** 1. row ***************************                  EVENT_NAME: **memory/temptable/physical_disk**                 COUNT_ALLOC: 0                  COUNT_FREE: 0   SUM_NUMBER_OF_BYTES_ALLOC: 0    SUM_NUMBER_OF_BYTES_FREE: 0              LOW_COUNT_USED: 0          CURRENT_COUNT_USED: 0             HIGH_COUNT_USED: 0    LOW_NUMBER_OF_BYTES_USED: 0CURRENT_NUMBER_OF_BYTES_USED: 0   HIGH_NUMBER_OF_BYTES_USED: 0*************************** 2. row ***************************                  EVENT_NAME: **memory/temptable/physical_ram**                 COUNT_ALLOC: 1                  COUNT_FREE: 0   SUM_NUMBER_OF_BYTES_ALLOC: 1048576    SUM_NUMBER_OF_BYTES_FREE: 0              LOW_COUNT_USED: 0          CURRENT_COUNT_USED: 1             HIGH_COUNT_USED: 1    LOW_NUMBER_OF_BYTES_USED: 0CURRENT_NUMBER_OF_BYTES_USED: 1048576   HIGH_NUMBER_OF_BYTES_USED: 10485762 rows in set (0.03 sec)

    以上 memory/temptable/physical_disk 代表放入磁盘上的临时表计数情况。

    memory/temptable/physical_ram 代表放入内存的临时表计数情况。

    那总结下MySQL 8.0 引入的 TempTable 引擎:

    默认内部临时表引擎。

    支持变长字符类型的实际存储。

    设置变量 temp_table_max_ram 来控制实际存储内存区域大小。

c# sql临时表的创建和查询问题。

代码:
SqlCommand cmd = new SqlCommand("select 班级,sum(人数) as 人数 into ##临时表 from 班级资料 group by 班级", con);

SqlCommand cmd0 = new SqlCommand("select * from ##临时表 where 班级='一班'", con);
SqlDataAdapter sda0 = new SqlDataAdapter(cmd0);
DataSet ds0 = new DataSet();
sda0.Fill(ds0,"t");

int sum0 = Convert.ToInt32(ds0.Tables[0].Rows[0]["人数"]);
SqlCommand cmddro = new SqlCommand("drop table ##临时表", con);

1、直接运行,提示:对象名 '##临时表' 无效。
2、若先在sql数据库中运行:select 班级,sum(人数) as 人数 into ##临时表 from 班级资料 group by 班级,则能正常运行。

初步怀疑代码"select 班级,sum(人数) as 人数 into ##临时表 from 班级资料 group by 班级"没运行成功。
求各位高手指导。。。

参考技术A 断点调试一下什么问题就出来了 参考技术B "select 班级,sum(人数) as 人数 into ##临时表 from 班级资料 group by 班级
去掉into XX零时表,group by 这里会报错(XX不包含在聚合函数中)说明有语法问题,丢SQL测试下就好了追问

谢谢~
我在sql中尝试过,运行“select 班级,sum(人数) as 人数 into ##临时表 from 班级资料 group by 班级”,然后再运行"select * from ##临时表", 出来结果是正确的。纠结啊。。。

追答

我测试了你的问题,这样写就可以了,加一个;把另一个语句放在它后面。结果如下:

 

 

但是我不建议你用这种方式,原因:

你这样的话等于在SQL又建立了一张表,具体如下,你后面再这样写应该就会出现我下面的这个问题,XX零时表已经存在。

 

建议这样写

select 班级,sum(人数) as 人数 from 班级资料 where  班级='一班' group by 班级,直接搜索你想要的。

追问

谢谢你,那我怎么才能读出这个sum(人数)这个结果呢?

其实我要建立这个临时表,目的是想sum统计后形成这个临时表,再从这个表中读取各个班级的sum值。如果无法形成临时表,我就无法得出这个sum值了。

追答

select 班级,sum(人数) as 人数 from 班级资料 where 班级='一班' group by 班级
现在这个语句的结果等同于
select 班级,sum(人数) as 人数 into ##临时表 from 班级资料 group by 班级
加上
select * from ##临时表

追问

那我如何获取的sum(人数)的值,例如要获取‘一班’的人数。

本回答被提问者和网友采纳

以上是关于关于mysql建立临时表的问题(新手入门)的主要内容,如果未能解决你的问题,请参考以下文章

mysql 临时表的建立和用途

mysql如何创建临时表

mysql 临时表的好处

关于Delphi内存表的使用说明

MySQL索引入门

关于sqlserver临时表的问题,请教高手!