发布网友 发布时间:2022-04-23 04:31
共2个回答
热心网友 时间:2022-04-08 01:22
使用视图的两种算法merge和temptable分别统计
表tb_phone中market_price大于4000的手机,然后查询视图查找出小于6000的手机
简单总结最终获取的结果:查询出market_price大于4000且小于6000的手机
表数据:
merge合并算法
合并的执行方式,每当执行的时候,先将视图的sql语句与外部查询视图的sql语句,合并在一起,最终执行.
以下是使用常规select语句模拟合并算法:
执行结果模拟与算法的结果相同:
temptable临时表算法
先执行视图再执行其他操作的查询
临时表模式,每当查询的时候,将视图所使用的select语句生成一个结果的临时表,再在当前的临时表内进行查询
以下是使用常规select语句模拟临时表算法:
执行结果模拟与算法的结果相同:
比较两种算法结果也相同,似乎是这样的,接下来的实例将不同
实例2
使用视图的两种算法merge和temptable分别统计
表tb_phone , 同类(cid)手机的最高价格(market_price)的产品
表数据:
首先可以考虑基本select语句的实现方式(这里就不再赘述):
先排序再分组
接下来使用两种算法:
merge合并算法
最后一句select模拟合并算法有语法错误的,order by 不能在 group by之前,这时执行会报错,但在视图中不会报错,而是直接跳过了错误部分order by 直接执行了
select * from tb_phone group by cid
最终结果(错误):
temptable临时表算法
发现执行结果与普通语句相同,模拟的语句同样正确
最终结果(正确):
热心网友 时间:2022-04-08 02:40
提到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 来控制实际存储内存区域大小。