扫描 mysql 表,为什么逐行获取结果集比在内存中完全检索它们要快得多



我们有一个包含 12,000,000+ 条记录的 innodb 表。

我使用两种方法使用 JDBC 从此表中SELECT *

Statement stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);

这种方式允许驱动程序逐行流式传输结果集,并且需要 7 秒才能完成扫描。

Statement stmt =conn.createStatement();

结果集完全检索并存储在内存中。而这种方式需要 21 秒!

只是感到困惑,为什么逐行获取结果集比检索完成到客户端内存中的结果集更快?逐行的方式不应该在网络传输上花费更多时间吗?

只是为了扩展我对 OP 的评论

这很可能是一个内存问题 - 将 12m 结果读取到内存中可能会导致分页,除非客户端有很多 RAM。一旦开始抖动磁盘,性能就会大大降低。值得注意的是,如果你开始增加RAM,JVM在如何解决>32G(它切换到64位指针)方面有一些怪癖,这意味着当你过渡到32G时,你实际上会失去可用内存,并且可能会有其他问题,这取决于你的代码是如何编写的。

为了正确看待事情,我们目前正在使用 elasticsearch 来索引 ~6000 万个文档。诚然,内存使用将更加复杂,因为它正在处理索引、缓存等......但我们不会考虑给它小于 16G 的 RAM 来获得高性能响应。我遇到过有人使用每个分片>100G 来制作非常大的记录集。

最新更新