tmp_table_size 和 max_heap_table_size MySQL 属性的经验法则

Nik*_*iko 7 mysql performance join sorting

标题几乎总结了问题本身:是否有关于tmp_table_sizemax_heap_table_sizeMySQL 属性的值的经验法则?

我的性能严重下降,这是由于 MySQL 使用磁盘空间对 JOIN 结果进行文件排序造成的。

增加tmp_table_sizemax_heap_table_size向3G解决的问题,但是这更多的是一种试错的办法。

有没有更可靠的方法来计算这两个的合适值?

Ric*_*mes 7

我建议为每个简单的 1% 内存。

  • max_heap_table_size是限制在一张ENGINE=MEMORY桌子上吗CREATE。没有多少人使用该引擎,如果您这样做,请在创建之前设置最大大小。

  • LEAST(max_heap_table_size, tmp_table_size)是让某些隐式临时表获得多大的上限。这些是在SELECTs(等)内部用于处理GROUP BYORDER BY、 子查询等的表。

由于每个连接都可以创建这些临时表,并且每个查询可能创建多个临时表,因此 1% 的 RAM 是一个相当“安全”的限制。当 MySQL 耗尽 RAM 时,操作系统会交换东西——交换 MySQL对性能来说很糟糕

此外,将这些设置得过大,您会从其他用途(例如,buffer_pool)中窃取 RAM,从而可能减慢所有查询的速度。

其他经验法则

另见SQL_BIG_RESULT


jyn*_*nus 5

尽可能延长tmp_table_size(及其依赖性, max_heap_table_size如果 MEMORY 用于临时内存引擎 - 最新版本使用 InnoDB)可能很诱人。毕竟,如果您使用更大的表大小运行相同的查询,它可能会更快!

但是,我能想到有两个不这样做的原因:

  • 如果临时表很大,您将浪费时间将行插入内存,然后将其复制到磁盘,然后继续插入行。根据查询的不同,您可能会发现尽快写入磁盘可能会更快。
  • 虽然设置大缓冲区似乎是个好主意,但内存并不是无限的 - 因此,如果每个查询/连接都将占用 3G 内存,您可能会用完它,并且由于虚拟内存交换而开始写入磁盘(这可能会导致 MySQL 由于内存不足错误而崩溃,或者速度慢得难以置信)。

现在,如果您只是运行一个查询,而不是同时运行多个查询(因此您不会遇到这些问题),并且它可以让您更快地运行,请随意增加它(但可能您可能想更改它)仅会话,因此它不会影响可能获得我提到的那些回归的其他查询)。

要计算一个好的值,请选择您希望查询占用的最大内存量(请注意,您还需要 . join_buffer_sizesort_buffer_sizeread_buffer_size其他缓冲区的内存)或您将生成的最大临时表,无论哪个较小。

您可以使用Created_tmp_disk_tablesCreated_tmp_tables变量来了解您在全局范围内创建了多少临时表和磁盘上的临时表(尽管有些是不可避免的 - 例如,堆表不允许 blob,并且某些查询将始终需要临时表,不与索引有关)。