经过一些搜索,我了解到问题可能是由我的SELECT id, name, date, score FROM student_grade ORDER BY id, date DESC
查询引起的,该查询创建了一个临时表。由于内存中的表太小,因此必须将其写入磁盘。并且表文件在某种程度上是有限的,因此错误。以下是我到目前为止的发现:
- 清理
rdsdbdata/tmp
是不可行的,因为这实际上无法通过RDS进行管理 - RDS示例本身有足够的磁盘空间,因此实际的磁盘空间应该不是问题。将
innodb_file_per_table
设置为ON
,我猜每个表都有自己的tmp文件,其大小是有限的? - 增加
tmp_table_size
和max_heap_table_size
(默认为16MB)可能会达到目的。我不知道有多大的尺寸,有推荐的尺寸吗?(有人说应该是DBInstanceClassMemory
的1%)。无论如何,我创建了一些修改的参数组,并配置数据库示例使用它。不知何故,tmp表的大小仍然是默认的(16MB)。我也被困在这里了。 - 如果没有
ORDER BY
部分,查询也可以工作。所以排序似乎是这里的问题,有一个工作吗? - 查询的输出文本文件(不包括
ORDER BY
部分)大约是500MB(约2亿条记录),应该是为tmp表设置的大小吗?
所以,我已经尝试了我能做的一切,我想我会联系云团队来帮助配置。但除此之外,是否有任何MySql配置,我应该修补?或者我应该对我的查询做什么SQL优化?
2条答案
按热度按时间6tr1vspr1#
所有InnoDB查询都应该按索引顺序读取行,所以如果你可以让它从一个顺序与你想要的最终顺序相匹配的索引中读取,那么
ORDER BY
将是一个空操作,它不需要排序任何东西。它只会按照读取的顺序返回行。所以你需要一个索引表,列
(id, date)
作为索引的最左边的列。但不幸的是,MySQL直到8.0版本才支持ASC和DESC列的索引,并且还没有基于MySQL 8.0的Amazon Aurora版本。Aurora所基于的MySQL 5.7只能使用ASC列创建索引。
因此,如果您希望结果使用索引,则必须更改结果的排序顺序。
ORDER BY id DESC, date DESC
或ORDER BY id ASC, date ASC
。两者都将使用索引。另外,你可能必须强制查询使用索引,因为如果你获取所有行,它将默认为表扫描,跳过索引。
我在这份解释报告中寻找的是“额外:使用文件排序”。
vlju58qv2#
我有一个类似的问题,同样的错误,我通过阅读这篇博客文章修复了我的问题:https://aws.amazon.com/blogs/database/best-practices-for-configuring-parameters-for-amazon-rds-for-mysql-part-1-parameters-related-to-performance/,然后我将tmp_table_size和max_heap_table_size修改为推荐的64MB。您可以在Aurora中为您的DB版本创建一个新的DB集群参数组。然后,搜索这两个变量,单击“编辑”,并按照文档的建议将它们修改为67,108,864字节(64 MB)、128 MB或512 MB。然后,将该参数组分配给数据库并应用更改。对于我的目的,这些变量的64 MB已经足够了。