MySQL(5.6)是否总是将整个查询结果集缓存在内存/磁盘上?

时间:2018-10-22 07:43:17

标签: mysql database

我需要将一些非常大的MySQL表转储到csv(托管在RDS上,所以没有SELECT INTO OUTFILE)。这些表远远大于其服务器上的可用内存。

如果我使用带有SELECT * FROM a_big_tablefetchmany()的python框架执行fetchone()来获取记录,则MySQL 5.6会尝试首先将整个表读入内存(我预计将导致缓存到磁盘),还是比这更聪明?

编辑:为澄清起见,我的意思是将整个结果集存储在MySQL缓存中(而不是Python!)。

第二次编辑:在第一次编辑中将“排序”错字更改为“存储”。关于此案的评论仍然有用!

2 个答案:

答案 0 :(得分:3)

服务器上已使用的内存量由缓冲池大小配置设置定义。几乎无需担心服务器端发生了什么。您的提取应用程序可能会成为瓶颈,因此写入转储的速度可能比MySQL输出的速度慢。服务器在获取数据时只负责填充缓冲区。从服务器的角度来看,获取一个较大的结果集比进行多个较小范围的查询更有效,对资源的需求也更少...

答案 1 :(得分:2)

通常在应用程序级别的数据库调用中,不返回整个结果集,而是返回指向结果集的游标。然后取决于应用程序语言(例如Python)来迭代该结果集并检索记录。

用于MySQL的Python连接器的documentation确认了这一点:

  

默认情况下,MySQL Connector / Python不会缓冲或预取结果。这意味着在执行查询后,您的程序将负责获取数据(重点是我的)。当查询返回大结果集时,这避免了过多的内存使用。如果您知道结果集足够小以至于可以一次处理所有内容,则可以通过将buffered设置为True来立即获取结果。也可以为每个游标设置此设置(请参见第10.2.6节“ MySQLConnection.cursor()方法”)。

     

在客户端程序获取查询结果之前,通常不会读取查询生成的结果。要自动使用和丢弃结果集,请将consume_results选项设置为True。结果是读取了所有结果,这对于大型结果集可能很慢。 (在这种情况下,最好关闭并重新打开连接。)

因此,从内存需求的角度来看,使用SELECT *查询,然后一次写入一个记录或一次写入记录组的策略应该可行。您的Python代码应该只需要尽可能多的内存来保存您要写入文件的当前记录。