最优MySQL临时表(内存表)配置?

时间:2010-07-09 17:38:39

标签: sql mysql performance optimization temp-tables

首先,我是优化mysql的新手。事实上,我在我的Web应用程序中(每秒大约400个查询),一个使用GROUP BY的查询,我无法避免,这是创建临时表的原因。我的配置是:

max_heap_table_size = 16M  
tmp_table_size = 32M  

结果:临时表到磁盘百分比+ - 12.5%

然后我根据this post

更改了我的设置
max_heap_table_size = 128M  
tmp_table_size = 128M

结果:临时表到磁盘百分比+ - 18%

结果没有预料到,不明白为什么。

这是错误的tmp_table_size = max_heap_table_size? 不应该增加尺寸?

查询

SELECT images, id  
FROM classifieds_ads   
WHERE  parent_category = '1' AND published='1' AND outdated='0'
GROUP BY aux_order  
ORDER BY date_lastmodified DESC  
LIMIT 0, 100;

EXPLAIN

| 1 |SIMPLE|classifieds_ads | ref |parent_category, published, combined_parent_oudated_published, oudated | combined_parent_oudated_published | 7 | const,const,const | 67552 | Using where; Using temporary; Using filesort |

1 个答案:

答案 0 :(得分:10)

EXPLAIN报告中的“使用临时”并不告诉我们临时表在磁盘上。它只告诉我们查询期望创建临时表。

如果临时表的大小小于tmp_table_size 小于max_heap_table_size,则临时表将保留在内存中。

Max_heap_table_size是MEMORY存储引擎中可以存在的最大表,无论该表是临时表还是非临时表。

Tmp_table_size是查询自动创建的表中最大的表。但无论如何,这不能大于max_heap_table_size。因此将tmp_table_size设置为大于max_heap_table_size没有任何好处。将这两个配置变量设置为相同的值是很常见的。

您可以监控创建的临时表数量,以及磁盘上有多少个:

mysql> show global status like 'Created%'; 
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 20    |
| Created_tmp_files       | 6     |
| Created_tmp_tables      | 43    |
+-------------------------+-------+

请注意,在此示例中,创建了43个临时表,但其中只有20个在磁盘上。

当增加tmp_table_size和max_heap_table_size的限制时,允许更大的临时表存在于内存中。

你可能会问,你需要多大的力量?您不一定需要使其足够大,以使每个临时表适合内存。您可能希望95%的临时表适合内存,只有剩余的稀有表位于磁盘上。那些最后5%可能非常大 - 比你想要使用的内存量大很多。

所以我的做法是保守地增加tmp_table_size和max_heap_table_size。然后观察Created_tmp_disk_tables的比率到Created_tmp_tables,看看我是否达到了让95%的人留在记忆中的目标(或者我想看的任何比例)。

不幸的是,MySQL没有一个很好的方法来告诉你临时表的大小。这将因每个查询而异,因此状态变量无法显示,它们只能显示已发生的次数。并且EXPLAIN实际上并不执行查询,因此无法准确预测它将匹配多少数据。

另一种选择是Percona Server,它是MySQL的一个改进版本。其中一个是log extra information in the slow-query log。额外字段中包含由给定查询创建的任何临时表的大小。