[英]Does MySQL (5.6) always cache the entire result set for a query in memory/on disk?
我需要将一些非常大的MySQL表转储到csv(托管在RDS上,所以没有SELECT INTO OUTFILE)。 这些表远远大于其服务器上的可用内存。
如果我使用带有fetchmany()
或fetchone()
的python框架执行SELECT * FROM a_big_table
来获取记录, MySQL 5.6
尝试首先将整个表读入内存(我希望这会导致缓存到磁盘),或者比这聪明吗?
编辑:为了澄清,我的意思是将整个结果集存储在MySQL缓存中(而不是Python!)。
第二次编辑:在第一次编辑中将“排序”错字更改为“存储”。 注释对于这种情况仍然有用!
服务器上已使用的内存量由缓冲池大小配置设置定义。 几乎无需担心服务器端发生了什么。 您的提取应用程序可能会成为瓶颈,因此写入转储的速度可能比MySQL输出的速度慢。 服务器在获取数据时只负责填充缓冲区。 从服务器的角度来看,获取一个更大的结果集比进行多个较小范围的查询更有效,对资源的需求也更少。
通常,在应用程序级别的数据库调用中,不会返回整个结果集,而是会返回指向结果集的游标。 然后由应用程序语言(例如Python)来迭代该结果集并检索记录。
MySQL的Python连接器的文档确认了这一点:
默认情况下,MySQL Connector / Python不缓冲或预取结果。 这意味着执行查询后,您的程序将负责获取数据 (重点是我的)。 当查询返回大结果集时,这避免了过多的内存使用。 如果您知道结果集足够小以至于可以一次处理所有内容,则可以通过将buffered设置为True来立即获取结果。 也可以为每个游标设置此设置(请参见第10.2.6节“ MySQLConnection.cursor()方法”)。
在客户端程序获取查询结果之前,通常不会读取查询生成的结果。 要自动使用和丢弃结果集,请将consume_results选项设置为True。 结果是读取了所有结果,这对于大型结果集可能很慢。 (在这种情况下,最好关闭并重新打开连接。)
因此,从内存需求的角度来看,使用SELECT *
查询,然后一次写入一个记录或一次写入记录组的策略应该可行。 您的Python代码仅需要尽可能多的内存来保存您尝试写入文件的当前记录。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.