Created_tmp_tables - xiaoboluo768/qianjinliangfang GitHub Wiki

  • 服务器执行语句时自动创建的内存中的临时表的数量,注意该变量是包含所有的内部临时表的数量(包含memory和on disk)
    • 在某些情况下,服务器在处理语句时创建内部临时表。用户无法直接控制发生这种情况的时间,服务器在以下条件下将创建临时表:
      • 评估UNION语句时
      • 评估一些视图,例如使用TEMPTABLE算法,UNION去重或UNION聚合的视图
      • 评估派生表(FROM子句中的子查询)
      • 为实现子查询或半连接物化视图而创建的表(请参见第8.2.2节“优化子查询,派生表和视图”)。
      • 评估包含ORDER BY子句和不同GROUP BY子句的语句(指的可能是两个语句使用到的列上都有独立的索引,而一个查询中是无法同时使用两个索引的,其中有一个操作无法使用到索引),或者ORDER BY或GROUP BY使用的列不都是驱动表的列(此时两个操作就算列有索引,没有使用到驱动表中的列是无法使用到索引的)
      • 评估DISTINCT与ORDER BY组合的可能需要临时表
      • 对于使用SQL_SMALL_RESULT修饰符的查询,MySQL使用内存中临时表,除非查询还包含必须需要使用磁盘临时表的元素(稍后描述)
      • 评估多表UPDATE语句
      • 评估GROUP_CONCAT()或COUNT(DISTINCT)表达式
    • 要在语句真正执行前确定语句是否需要临时表,请使用EXPLAIN并检查Extra列以的值可以确认是否为使用了临时表,如果使用了,可以看到Using temporary
    • 当服务器创建内部临时表(内存或磁盘上)时,它会增加Created_tmp_tables状态变量。如果服务器在磁盘上创建表,它会增加Created_tmp_disk_tables状态变量
    • 某些查询场景不能使用内存中临时表,在这种情况下,服务器使用磁盘表替代,这些可能的场景如下:
      • 在表中存在BLOB或TEXT列
      • 在GROUP BY或DISTINCT子句中有字符串列的,对于binary string大于512字节,对于nonbinary string大于512字符。 (在MySQL 5.6.15之前,不管字符串类型,都限制为512字节,超过即不能使用内存临时表)
      • 如果使用UNION或UNION ALL,则在SELECT列表中存在任何列最大长度大于512个字符或512个字节时(对于binary string大于512字节,对于nonbinary string大于512字符)
      • SHOW COLUMNS和DESCRIBE语句使用BLOB作为某些列的类型,结果集会使用磁盘临时表
    • 内存临时表保存在内存中并由MEMORY存储引擎处理,磁盘临时表存储在磁盘上并由MyISAM存储引擎处理
    • 如果内部临时表被创建为内存表,但后续主键变大超过了限制,MySQL会自动将其转换为磁盘表。内存中临时表的最大大小由tmp_table_size和max_heap_table_size的值中较小者确定。这不同于使用CREATE TABLE显式创建的MEMORY表:对于这些表,只有max_heap_table_size系统变量确定允许表增长多少,并且不会转换为磁盘表
    • 内存中临时表由MEMORY存储引擎管理,该引擎使用固定长度的行格式。 VARCHAR和VARBINARY列按照最大长度分配固定长度的内存,实际上将它们转换为CHAR和BINARY列,磁盘临时表由MyISAM存储引擎使用变长行格式管理。字符串列是使用变长的,按数据的大小动态分配,与使用固定长度行的磁盘表相比,这减少了磁盘I / O、空间以及处理时间(在MySQL 5.6.5之前,磁盘临时表存储使用固定长度的行)
    • 对于最初在内存中创建内部临时表的语句,然后预估一定会导致会转换为磁盘表的查询,可以通过跳过转换步骤并在直接创建磁盘临时表避免内部转换的时间,可能有更好的性能。通过big_tables系统变量可实现强制内部临时表直接使用磁盘临时表(注意,该变量只能碰到必须要使用大量临时表的语句,且只能session级别修改,不要全局修改,不要放到配置文件中)

上一篇:Created_tmp_disk_tables | 下一篇:Aborted_clients