为什么 MySQL 在磁盘上创建这么多临时表?

ana*_*air 15 mysql innodb myisam memory

任何配置错误是否会导致 mysql..mysql 调谐器显示创建过多的临时表

Current max_heap_table_size = 200 M
Current tmp_table_size = 200 M
Of 17158 temp tables, 30% were created on disk

table_open_cache = 125 tables
table_definition_cache = 256 tables
You have a total of 97 tables
You have 125 open tables.
Current table_cache hit rate is 3%
Run Code Online (Sandbox Code Playgroud)

早期的临时表是“在 23725 个临时表中 38% 是在磁盘上创建的”,但我将 max_heap 和 tmp_table 从 16m 更改为 200m 并降低到 30%。

配置:

engine myisam 
group_concat_max_len = 32768
key_buffer_size = 3.7 GB,
thread_stack = 256k,
table_cache = 125
query_cache_limit = 1M
query_cache_size = 16M
join_buffer_size = 2.00 M
max_connections = 800
Run Code Online (Sandbox Code Playgroud)

另一个具有默认配置的系统显示“在 23725 个临时表中,1% 是在磁盘上创建的”具有相同的数据库。

我尝试在出现此问题的机器上更改为默认值,但它仍然显示“在 580 个临时表中,16% 是在磁盘上创建的”。

我正在使用 Ubuntu 11.4 64 位和 48 GB 内存。任何人都可以提出解决方案吗?

使用“group by”将表上的数据库引擎从“myisam”更改为“memory”会解决这个问题吗?如此处所述:http : //www.mysqlperformanceblog.com/2007/08/16/how-much-overhead-is-caused-by-on-disk-temporary-tables/

Aar*_*own 18

mysqltuner 很少提供任何有用的信息。它主要使用与“命中率”无关的统计数据,并对可接受的小部件数量进行任意限制。如果您没有面临性能问题,那么您实际上不需要解决它呈现给您的任何问题。话虽如此,这里有一些关于临时表的背景信息......

MySQL 内部使用 MEMORY 存储引擎来创建隐式临时表。在磁盘临时表上使用 MyISAM 存储引擎。

在以下情况下在磁盘上创建临时表:

  • 存在 TEXT 或 BLOB 字段(因为 MEMORY 不支持这些类型)
  • 生成的隐式临时表的大小超过tmp_table_sizemax_heap_table_size
  • 如果将超过 512 个字节的列与 GROUP BY 或 UNION 或 ORDER BY 一起使用

阅读有关内部临时表的MySQL 文档了解更多详细信息。

你能做些什么呢?假设它实际上代表了一个性能问题(而不仅仅是在智力上打扰你):

  • 避免使用 TEXT/BLOB 字段,而是尽可能使用适当大小的 VARCHAR 或 CHAR 字段。
  • 如果 TEXT/BLOB 不可避免,请将它们隔离到具有外键关系的单独表中,并仅在需要时才加入。
  • 像对待上述 TEXT/BLOB 字段一样对待超过 512 字节的大列。
  • Make sure your queries are returning only the result set you need (appropriately selective WHERE clauses, avoid SELECT *)
  • 避免子查询并用连接替换它们,尤其是当它们返回一个大的结果集时
  • 最后的手段 - 提高tmp_table_sizemax_heap_table_size。除非您发现无法优化查询,否则不要这样做。

如果您担心自己的 MySQL 配置并且对自己的可用设置不满意,您可能需要查看Percona 配置向导作为起点。

使用“group by”将表上的数据库引擎从“myisam”更改为“memory”会解决这个问题吗?如此处所述

不,它不会,它会使您的表永远不会持久化到磁盘。不要这样做。