gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区

站長資訊網
最全最豐富的資訊網站

MySQL臨時表深入理解

MySQL臨時表深入理解

概述

MySQL中臨時表主要有兩類,包括外部臨時表和內部臨時表。外部臨時表是通過語句create temporary table…創建的臨時表,臨時表只在本會話有效,會話斷開后,臨時表數據會自動清理。內部臨時表主要有兩類,一類是information_schema中臨時表,另一類是會話執行查詢時,如果執行計劃中包含有“Using temporary”時,會產生臨時表。內部臨時表與外部臨時表的一個區別在于,我們看不到內部臨時表的表結構定義文件frm。而外部臨時表的表定義文件frm,一般是以#sql{進程id}_{線程id}_序列號組成,因此不同會話可以創建同名的臨時表。

臨時表

臨時表與普通表的主要區別在于是否在實例,會話,或語句結束后,自動清理數據。比如,內部臨時表,我們在一個查詢中,如果要存儲中間結果集,而查詢結束后,臨時表就會自動回收,不會影響用戶表結構和數據。另外就是,不同會話的臨時表可以重名,所有多個會話執行查詢時,如果要使用臨時表,不會有重名的擔憂。5.7引入了臨時表空間后,所有臨時表都存儲在臨時表空間(非壓縮)中,臨時表空間的數據可以復用。臨時表并非只支持Innodb引擎,還支持myisam引擎,memory引擎等。因此,臨時表我們看不到實體(idb文件),但其實不一定是內存表,也可能存儲在臨時表空間中。

臨時表 VS 內存表

臨時表既可以innodb引擎表,也可以是memory引擎表。這里所謂的內存表,是說memory引擎表,通過建表語句create table …engine=memory,數據全部在內存,表結構通過frm管理,同樣的內部的memory引擎表,也是看不到frm文件中,甚至看不到information_schema在磁盤上的目錄。在MySQL內部,information_schema里面的臨時表就包含兩類:innodb引擎的臨時表和memory引擎的臨時表。比如TABLES表屬于memory臨時表,而columns,processlist,屬于innodb引擎臨時表。內存表所有數據都在內存中,在內存中數據結構是一個數組(堆表),所有數據操作都在內存中完成,對于小數據量場景,速度比較快(不涉及物理IO操作)。但內存畢竟是有限的資源,因此,如果數據量比較大,則不適合用內存表,而是選擇用磁盤臨時表(innodb引擎),這種臨時表采用B+樹存儲結構(innodb引擎),innodb的bufferpool資源是共享的,臨時表的數據可能會對bufferpool的熱數據有一定的影響,另外,操作可能涉及到物理IO。memory引擎表實際上也是可以創建索引的,包括Btree索引和Hash索引,所以查詢速度很快,主要缺陷是內存資源有限。

使用臨時表的場景

前面提到執行計劃中包含有“Using temporary”時,會使用臨時表,這里列兩個主要的場景。

測試表結構如下:

mysql> show create table t1_normalG *************************** 1. row ***************************        Table: t1_normal Create Table: CREATE TABLE `t1_normal` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `c1` int(11) DEFAULT NULL,   `c2` int(11) DEFAULT NULL,   `c3` int(11) DEFAULT NULL,   `c4` int(11) DEFAULT NULL,   PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=770023 DEFAULT CHARSET=utf8

場景1:union

mysql> explain select * from t1_normal union select * from t1_normal;  +----+--------------+------------+------------+------+---------------+------+---------+------+--------+----------+-----------------+  | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |  +----+--------------+------------+------------+------+---------------+------+---------+------+--------+----------+-----------------+  | 1 | PRIMARY | t1_normal | NULL | ALL | NULL | NULL | NULL | NULL | 523848 | 100.00 | NULL | | 2 | UNION | t1_normal | NULL | ALL | NULL | NULL | NULL | NULL | 523848 | 100.00 | NULL | | NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary | +----+--------------+------------+------------+------+---------------+------+---------+------+--------+----------+-----------------+

union操作的含義是,取兩個子查詢結果的并集,重復的數據只保留一行,通過建立一個帶主鍵的臨時表,就可以解決“去重”問題,通過臨時表存儲最終的結果集,所以能看到執行計劃中Extra這一項里面有“Using temporary”。與union相關的一個操作是union all,后者也是將兩個子查詢結果合并,但不解決重復問題。所以對于union all,沒有“去重”的含義,因此也就不需要臨時表了。

mysql> explain select * from t1_normal  union  all select * from t1_normal; +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+-------+ | id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra | +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+-------+ |  1 | PRIMARY     | t1_normal | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 523848 |   100.00 | NULL  | |  2 | UNION       | t1_normal | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 523848 |   100.00 | NULL  | +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+-------+

場景2:group by

mysql> explain select c1,count(*) as count from t1_normal group by c1; +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+---------------------------------+ | id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra                           | +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+---------------------------------+ |  1 | SIMPLE      | t1_normal | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 523848 |   100.00 | Using temporary; Using filesort | +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+---------------------------------+

group by的含義是按指定列分組,并默認按照指定列有序。上面的SQL語句含義是將t1_normal中的數據按c1列的值分組,統計每種c1列值的記錄數目。從執行計劃中我們看到了"Using temporary;Using filesort",對于group by而言,我們首先需要統計每個值出現的數目,這就需要借助臨時表來快速定位,如果不存在,則插入一條記錄,如果存在,并累加計數,所以看到了"Using temporary";然后又因為group by隱含了排序含義,所以還需要按照c1列進行對記錄排序,所以看到了"Using filesort"。

1).消除filesort

實際上,group by也可以顯示消除“排序含義”。

mysql> explain select c1,count(*) as count from t1_normal group by c1 order by null; +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+-----------------+ | id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra           | +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+-----------------+ |  1 | SIMPLE      | t1_normal | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 523848 |   100.00 | Using temporary | +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+-----------------+

可以看到,語句中加上“order by null”后,執行計劃中,不再出現“Using filesort”。

2).消除臨時表

mysql> explain select SQL_BIG_RESULT c1,count(*) as count from t1_normal group by c1; +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+ | 1 | SIMPLE | t1_normal | NULL | ALL | NULL | NULL | NULL | NULL | 523848 | 100.00 | Using filesort | +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+

可以看到執行計劃中已經沒有了“Using temporary”,所以group by并非一定依賴臨時表,臨時表在group by中的作用主要是“去重”。所以,實際上有另外一種方式,不使用臨時表,直接利用sort_buffer排序(sort_buffer不夠時,進行文件排序,具體而言是每一個有序數組作為一個單獨文件,然后進行外排歸并),然后再掃描得到聚合后的結果集。

3).SQL_BIG_RESULT

同時我們語句中用到了“SQL_BIG_RESULT”這個hint,正是因為這個hint導致了我們沒有使用臨時表,先說說SQL_BIG_RESULT和SQL_SMALL_RESULT的含義。

SQL_SMALL_RESULT:顯示指定用內存表(memory引擎)

SQL_BIG_RESULT:顯示指定用磁盤臨時表(myisam引擎或innodb引擎)

兩者區別在于,使用磁盤臨時表可以借助主鍵做去重排序,適合大數據量;使用內存表寫入更快,然后在內存中排序,適合小數據量。下面是從MySQL手冊中摘錄的說明。

SQL_BIG_RESULT or SQL_SMALL_RESULT can be used with GROUP BY or DISTINCT to tell the optimizer that the result set has many rows or is small, respectively.

For SQL_BIG_RESULT, MySQL directly uses disk-based temporary tables if needed, and prefers sorting to using a temporary table with a key on the GROUP BY elements.

For SQL_SMALL_RESULT, MySQL uses fast temporary tables to store the resulting table instead of using sorting.

This should not normally be needed.

回到問題本身,這里MySQL優化器根據hint知道需要使用磁盤臨時表,而最終直接選擇了數組存儲+文件排序這種更輕量的方式。

如何避免使用臨時表

通常的SQL優化方式是讓group by 的列建立索引,那么執行group by時,直接按索引掃描該列,并統計即可,也就不需要temporary和filesort了。

mysql> alter table t1_normal add index idx_c1(c1); Query OK, 0 rows affected (1 min 23.82 sec) Records: 0  Duplicates: 0  Warnings: 0 mysql> explain select c1,count(*) as count from t1_normal group by c1 order by null; +----+-------------+-----------+------------+-------+---------------+--------+---------+------+--------+----------+-------------+ | id | select_type | table     | partitions | type  | possible_keys | key    | key_len | ref  | rows   | filtered | Extra       | +----+-------------+-----------+------------+-------+---------------+--------+---------+------+--------+----------+-------------+ |  1 | SIMPLE      | t1_normal | NULL       | index | idx_c1        | idx_c1 | 5       | NULL | 523848 |   100.00 | Using index | +----+-------------+-----------+------------+-------+---------------+--------+---------+------+--------+----------+-------------+

相關參數與狀態監控

1).參數說明

max_heap_table_size

This variable sets the maximum size to which user-created MEMORY tables are permitted to grow,The value of the variable is used to calculate MEMORY table MAX_ROWS values.

這個參數主要針對用戶創建的MEMORY表,限制內存表最大空間大小,注意不是記錄數目,與單條記錄的長度有關。如果超出閥值,則報錯。ERROR 1114 (HY000): The table 'xxx' is full

tmp_table_size

The maximum size of internal in-memory temporary tables.

對于用戶手工創建的內存表,只有參數max_heap_table_size起作用;對于內部產生的內存表,則參數max_heap_table_size和tmp_table_size同時起作用。對于內部產生的內存表(比如union,group by等產生的臨時表),先是采用內存表(memory表),然后超過設置的閥值(max_heap_table_size,tmp_table_size)就會轉為磁盤表,使用innodb引擎或者myisam引擎,通過參數internal_tmp_disk_storage_engine指定。

tmpdir

如果內存臨時表超出了限制,MySQL就會自動地把它轉化為基于磁盤的MyISAM表,存儲在指定的tmpdir目錄下

2.狀態監控

Created_tmp_tables,內部臨時表數目

Created_tmp_disk_tables,磁盤臨時表數目

3.information_schema相關

mysql> create temporary table t1_tmp(id int primary key,c1 int); Query OK, 0 rows affected (0.02 sec) mysql> SELECT * FROM information_schema.INNODB_TEMP_TABLE_INFO; +----------+---------------+--------+-------+----------------------+---------------+ | TABLE_ID | NAME | N_COLS | SPACE | PER_TABLE_TABLESPACE | IS_COMPRESSED | +----------+---------------+--------+-------+----------------------+---------------+ | 10063 | #sql693d_29_0 | 5 | 45 | FALSE | FALSE | +----------+---------------+--------+-------+----------------------+---------------+

總結

本文詳細介紹了MySQL中臨時表的核心特征,按需創建并且自動銷毀,對于純內存的數據特別適合,但為了避免內存不可控,實際上不僅僅有內存臨時表,還有磁盤臨時表。臨時表和內存表本沒有直接關聯,因為臨時表既可以是memory引擎,又可以innodb引擎將兩者聯系到了一起,實際上不同類別的臨時表也是用到了不同引擎的優勢。臨時表使用的典型場景是union和group by。為了消除臨時表,我們需要對group by列添加索引,或者對于大結果集,使用SQL_BIG_RESULT等。最后本文介紹了臨時表相關的參數和狀態變量,以及information_schema中的臨時表信息。

推薦教程:《MySQL教程》

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区
国产av麻豆mag剧集| 网站在线你懂的| 一本—道久久a久久精品蜜桃| 欧美日韩一区二区在线免费观看| 欧美在线一区视频| 日本阿v视频在线观看| 韩国黄色一级大片| 第九区2中文字幕| 精品久久久无码人妻字幂| 公共露出暴露狂另类av| 久久视频免费在线| 国产精品久久久久9999爆乳| 欧美一区二区视频在线播放| 欧美视频在线免费播放| 九九九九免费视频| 青青青国产在线视频| 亚洲黄色小视频在线观看| 亚洲欧美国产中文| 久久久无码中文字幕久...| 亚洲激情免费视频| av免费看网址| 欧美视频免费播放| 加勒比av中文字幕| 免费极品av一视觉盛宴| 久久久久久久中文| 91制片厂毛片| 欧美大黑帍在线播放| 黄色免费视频大全| 久久6免费视频| 成人性生活视频免费看| jizz18女人| 91网站在线观看免费| 在线视频日韩一区| 性生活免费观看视频| 免费激情视频在线观看| 特级西西人体www高清大胆| 六月丁香婷婷在线| 免费黄频在线观看| 十八禁视频网站在线观看| 美女黄色片网站| 亚洲国产精品毛片av不卡在线| 99re99热| 黄色一级片免费的| 女性女同性aⅴ免费观女性恋| 亚洲制服在线观看| 美女喷白浆视频| 男女啪啪免费视频网站| 99精品一级欧美片免费播放| 国产成人黄色网址| 久久美女福利视频| 日韩精品一区二区免费| 日日噜噜夜夜狠狠久久丁香五月| 不卡av免费在线| 国产h视频在线播放| 国产一二三四区在线观看| 亚洲 国产 图片| 亚洲少妇第一页| 欧美黄色一级片视频| 免费国产黄色网址| av高清在线免费观看| 无颜之月在线看| 91亚洲一区二区| 国产精品久久久久久久99| 97公开免费视频| 一区二区三区国产免费| 日本www.色| 免费看污污网站| 亚洲另类第一页| 日韩在线一区视频| 日韩精品视频网址| 少妇熟女一区二区| 成年丰满熟妇午夜免费视频| 黄网站色视频免费观看| 8x8ⅹ国产精品一区二区二区| 日本美女爱爱视频| 男人的天堂狠狠干| 最近免费中文字幕中文高清百度| 一级特黄性色生活片| 老司机午夜性大片| 免费看污污视频| 欧美性潮喷xxxxx免费视频看| 欧美日韩不卡在线视频| 国产免费一区二区三区视频| 亚洲国产精品毛片av不卡在线| 日本美女高潮视频| 最近中文字幕免费mv| 无码粉嫩虎白一线天在线观看 | 欧美一级小视频| 黄色网址在线免费看| 久久精品国产sm调教网站演员| 精品www久久久久奶水| 亚洲制服中文字幕| 99在线精品免费视频| 日本特黄a级片| 久久人人爽人人爽人人av| 日本在线观看a| 91成人在线视频观看| 国产极品美女高潮无套久久久| 中文字幕色网站| a天堂资源在线观看| 99re精彩视频| 欧美激情视频免费看| 天天影视色综合| 丰满爆乳一区二区三区| 中文国产在线观看| 日韩精品一区二区三区久久| 又色又爽又黄视频| 内射国产内射夫妻免费频道| 加勒比av中文字幕| 无码aⅴ精品一区二区三区浪潮| 好色先生视频污| 91亚洲免费视频| www日韩视频| www在线观看免费| 美女av免费观看| 一级日本黄色片| 欧美成人福利在线观看| 欧美成人xxxxx| 日韩欧美一区二| 久久这里只有精品18| 肉色超薄丝袜脚交| 手机av在线网站| 中文字幕久久av| 一区二区三区视频网| 无码精品国产一区二区三区免费| 老太脱裤让老头玩ⅹxxxx| 国产va亚洲va在线va| 97av中文字幕| 日本人妻伦在线中文字幕| 久久香蕉视频网站| 欧美激情亚洲天堂| www.一区二区.com| 国产曰肥老太婆无遮挡| 五月丁香综合缴情六月小说| www.日本在线播放| 欧美日韩一道本| 国产女女做受ⅹxx高潮| 国产第一页视频| 欧美成人三级在线播放| 天堂av2020| 免费成人进口网站| 欧美一区二区视频在线播放| 日本五级黄色片| 99精品视频播放| 一区二区三区国产免费| 亚洲精品视频三区| 97免费视频观看| 日本精品www| 欧美性受xxxxxx黑人xyx性爽| 特黄特黄一级片| 久艹视频在线免费观看| 久久久久久久久久久久久久国产| 欧美婷婷精品激情| 一级黄色片播放| 日韩手机在线观看视频| 亚洲天堂av一区二区三区| www插插插无码免费视频网站| 无码人妻h动漫| 日本免费在线视频观看| 日韩精品一区二区三区久久| 色播五月激情五月| 日本精品久久久久久久久久 | 免费精品99久久国产综合精品应用| 婷婷视频在线播放| 国产97色在线 | 日韩| 久久久久久久久久久久久国产| 日韩av高清在线看片| 图片区乱熟图片区亚洲| 日韩欧美在线播放视频| 懂色av一区二区三区四区五区| 九色在线视频观看| 久久精品一二三四| 天天综合网日韩| 青青视频在线播放| 成人在线观看毛片| 国产三级精品三级在线| 亚洲爆乳无码专区| 无码 制服 丝袜 国产 另类| 日本高清一区二区视频| av无码精品一区二区三区| 老太脱裤子让老头玩xxxxx| 99精品一区二区三区的区别| 美女网站色免费| 国产成人av影视| 草草久久久无码国产专区| 91传媒免费视频| 亚洲高潮无码久久| 欧美日韩理论片| 国产一级免费大片| 狠狠操狠狠干视频| 手机av在线网| 男生操女生视频在线观看 | 国产四区在线观看| 中文字幕66页| 伊人影院综合在线| 色天使在线观看| 一本之道在线视频| 四虎影院一区二区| 日日噜噜噜夜夜爽爽| 国产又粗又猛大又黄又爽|