源码链接:https://dev.mysql.com/doc/refman/5.7/en/internal-temporary-tables.html在某些情况下,服务器是在处理Sql语句时创建内部临时表。用户无法直接控制何时发生这种情况。服务器在以下条件下创建临时表:(Evaluation有什么特殊含义吗?我翻译成evaluation)UNION语句的求值,有一些例外情况后面会讲到。评估视图,例如使用TEMPTABLE算法、UNION或聚合的视图。派生表(FROM子句中的子查询)。为子查询或半连接具体化创建表。评估包含ORDERBY子句和不同GROUPBY子句的语句,或者ORDERBY或GROUPBY包含来自连接队列中第一个表以外的表的列的语句。评估与ORDERBY查询相结合的DISTINCT可能需要一个临时表。对于带有SQL_SMALL_RESULT修饰符的查询,MySQL使用内存中的临时表,除非查询还包含需要磁盘存储的元素(稍后描述)。评估多表UPDATE语句。评估GROUP_CONCAT()或COUNT(DISTINCT)表达式。要确定语句是否需要临时表,请使用EXPLAIN并检查Extra列以查看是否显示Usingtemporary(请参阅第9.8.1节,“使用EXPLAIN优化查询”)。对于派生或物理化的临时表,EXPLAIN不一定说Usingtemporary。当服务器创建内部临时表(在内存或磁盘上)时,Created_tmp_tables状态变量会递增。如果服务器在磁盘上创建表(最初或通过转换内存表),它会增加Created_tmp_disk_tables状态变量。某些查询条件阻止使用内存中的临时表,在这种情况下服务器使用磁盘表:表中存在BLOB或TEXT列SELECT中任何字符串列的最大长度大于512(二进制字符串的字数)listsection,charactersotherthanbinarycharacters),SHOWCOLUMNS和DESCRIBE语句如果使用UNION或UNIONALL则使用BLOB作为某些字段的数据类型,因此用于结果的临时表是磁盘表。服务器不使用与某些条件语句匹配的UNION临时表。相反,它保留了从临时表创建的唯一数据结构,以对结果列执行必要的类型转换。该表未完全实例化,也没有写入或读取任何行;行直接发送给客户端。结果是减少了内存和磁盘需求,并且第一行发送到客户端之前的延迟更小,因为服务器不需要等到最后一个查询块被执行。EXPLAIN优化器跟踪输出反映了此执行策略:UNIONRESULT查询块不存在,因为该块对应于从临时表读取的部分。这些条件符合UNION的条件,不需要临时表:union是UNIONALL,而不是UNION或UNIONDISTINCT。没有全局ORDERBY子句。union不是{INSERT|的顶级语句的查询块REPLACE}...SELECT操作。StorageEnginesforTemporaryTables临时表存储格式StorageEngineInternalforTemporaryTables临时表可以保存在内存中并由MEMORY存储引擎处理,或者使用InnoDB或MyISAM存储引擎存储在磁盘上。如果一个表是内部临时表,存储在内存中,但变得太大,MySQL会自动将其转换为磁盘表。内存临时表的最大大小由tmp_table_size和max_heap_table_size中的较小者决定。这不同于使用CREATETABLE显式创建的内存表,对于后者只有max_heap_table_size系统变量确定允许表增长的大小,并且没有转换为磁盘格式。internal_tmp_disk_storage_engine系统变量确定服务器使用哪个存储引擎来管理磁盘上的内部临时表。允许的值是INNODB(默认)和MYISAM。**注意**使用`internal_tmp_disk_storage_engine=INNODB`生成超过`InnoDB`行或列限制的临时表的查询,返回行大小太大或列太多错误。解决方案是将`internal_tmp_disk_storage_engine`设置为`MYISAM`。临时表存储格式内存中的临时表由MEMORY存储引擎管理,它使用固定长度的行格式。VARCHAR和VARBINARY列值被填充到最大列长度,有效地将它们存储为CHAR和BINARY列。磁盘上的临时表由InnoDB或MyISAM存储引擎管理(取决于internal_tmp_disk_storage_engine设置)。两个引擎都使用动态宽度行格式存储临时表。列只需要尽可能多的存储空间,与使用固定长度行的磁盘表相比,减少了磁盘I/O和空间要求以及处理时间。对于最初在内存中创建内部临时表然后将其转换为磁盘表的语句,可以通过跳过转换步骤并在磁盘上创建表来获得更好的性能。big_tables系统变量可用于强制内部临时表的磁盘存储。如果翻译有什么问题,请多多指教。
