Mysql tmp_table_size max_heap_table_size

在我的服务器2天前,我的tmp_table_size = max_heap_table_size(16M)

我做了一个每小时运行一次的cron作业,并从以下版本生成一个报告: created_tmp_disk_tablescreated_tmp_filescreated_tmp_tables

在我的报告中: created_tmp_disk_tables + created_tmp_files + created_tmp_tables =我临时数据的100%

接着就,随即 :

  1. tmp_table_size = max_heap_table_size = 16M报告告诉我下一个平均报告:
    • 27.37%(created_tmp_disk_tables)
    • 1.16%(created_tmp_files)
    • 71.48%(created_tmp_tables)

我怎样才能优化这些结果?

  1. 在第一个小时内tmp_table_size = max_heap_table_size = 20M

    • 23.48%(created_tmp_disk_tables)
    • 32.44%(created_tmp_files)
    • 44.07%(created_tmp_tables)

7小时后(重启后):

  • 21.70%(created_tmp_disk_tables)
  • 33.75%(created_tmp_files)
  • 44.55%(created_tmp_tables)

这不是我所期望的。

  • 磁盘表从27.37%下降到21.70% – >预计更多
  • 临时文件从1.16%上升到33.75% – >为什么?
  • 记忆表从71.48%下降到44.55% – >奇怪; 预计会上涨

无论何时增加tmp_table_sizemax_heap_table_size ,请记住,设置这些不会使查询performance得更好。 这实际上使得效率低下的查询比以前更糟糕。 在什么情况下?

当一个查询执行连接或sorting(通过ORDER BY )没有索引的好处时,一个临时表必须在内存中形成。 这会增加Created_tmp_tables

如果临时表增长到tmp_table_size中的字节数并需要更多的空间呢? 以下一系列事件发生:

  1. 查询处理必须停止
  2. 在磁盘上创build一个临时表
  3. 将基于内存的临时表的内容传输到基于磁盘的临时表中
  4. 放在基于内存的临时表中
  5. 查询处理继续使用基于磁盘的临时表

这个过程递增了Created_tmp_disk_tables

了解这些机制,让我们来探讨在每个实例中发生的事情

磁盘表从27.37%下降到21.70% – >预计更多

如果之前运行的查询将结果caching在RAM中,则很容易发生这种情况。 这将消除从一开始处理查询的需要,而不是重新创build相同的大临时表。

临时文件从1.16%上升到33.75% – >为什么?

这并不奇怪。 这只是表明有一些事实,即有需要临时表的查询。 他们是先在RAM中创build的。 这只是表示查询不能很好地join(也许join_buffer_size太小)或ORDER BY非索引列或具有临时表的列(可能sort_buffer_size太小)。

记忆表从71.48%下降到44.55% – >奇怪; 预计会上涨

这也不奇怪。 如果具有相同值的相同查询的调用足够多,则可以通过完成来自先前caching的结果的查询来先占sorting和连接。

build议

鉴于这些事情,这里是可以调整的:

  • join_buffer_size
  • sort_buffer_size的值
  • 创build将被使用的索引
    • 通过eq_ref连接
    • 按顺序通过索引扫描进行sorting

总体目标应该是尽可能防止临时表创build。 简单地增加tmp_table_sizemax_heap_table_size会导致效率低下的查询和缺乏合适的索引的表运行横行。