【问题标题】:Overhead of data transfer from a MySQL database using PreparedStatement使用 PreparedStatement 从 MySQL 数据库传输数据的开销
【发布时间】:2014-02-16 04:33:24
【问题描述】:

这不是关于查询优化的问题。而是对来自 MySQL 5.5.27 (Amazon RDS) 的数据传输速率的预期进行全面检查。

在运行特别繁重的查询时,MySQL Workbench 显示的数据传输率约为 1MB/s,查询运行时间约为 420 秒。这增加了大约 420M 字节的正在传输的数据。

如果将此数据保存到一个简单的文本文件中,文件的大小最终会小于 7M 字节。由于 ResultSet 的元数据、JDBC 驱动程序机制等,我当然希望看到一些开销。但是 420M 与 7M 对我来说似乎是一个非常可怕的比例。或者,这正常吗?

非常感谢任何反馈。 非常感谢!

PS。更多细节:
-JDBC驱动是mysql-connector-java-5.1.13
-数据在 Amazon RDS 和 EC2 实例之间传输
-Java 1.6 PreparedStatement 用于执行查询

【问题讨论】:

  • 您基于时间的假设是没有根据的。数据传输率并不是消耗时间的唯一原因。不要在几秒钟内完成 MB。

标签: mysql performance jdbc prepared-statement resultset


【解决方案1】:

Wireshark 是一款出色的免费和开源 (GPL) 网络分析工具,在这种情况下可以发挥出色的作用。我运行了以下测试来查看到“正常”MySQL 服务器的“典型”JDBC 连接可能会产生多少流量。

我在我的测试服务器上的 MySQL (5.5.29-0ubuntu0.12.04.2) 中创建了一个名为 jdbctest 的表。

CREATE TABLE `jdbctest` (
  `id` int(11) DEFAULT NULL,
  `textcol` varchar(6) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我用 100,000 行表单填充它

    id  textcol
------  -------
     1  ABCDEF
     2  ABCDEF
     3  ABCDEF
...
100000  ABCDEF

每个 id 值 4 个字节和每个 textcol 值 6 个字节,检索所有 100,000 行应该代表大约 1 MB 的数据。

我启动了 Wireshark,开始跟踪,并运行以下使用 mysql-connector-java-5.1.26 的 Java 代码:

import java.sql.*;

public class mysqlTestMain {
    static Connection dbConnection = null;

    public static void main(String[] args) {
        try {
            String myConnectionString = "";
            myConnectionString =
                    "jdbc:mysql://192.168.1.3:3306/mytestdb";
            dbConnection = DriverManager.getConnection(myConnectionString, "root", "whatever");
            PreparedStatement stmt = dbConnection.prepareStatement("SELECT * FROM jdbctest");
            ResultSet rs = stmt.executeQuery();
            int i = 0;
            int j = 0;
            String s = "";
            while (rs.next()) {
                i++;
                j = rs.getInt("id");
                s = rs.getString("textcol");
            }
            System.out.println(String.format("Finished reading %d rows.", i));
            rs.close();
            stmt.close();
            dbConnection.close();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }
}

控制台输出确认我已检索到所有 100,000 行。

查看Wireshark trace的总结,发现:

Packets captured: 1811
Avg. packet size: 992.708 bytes
Bytes: 1797795

按方向细分

                   packets    bytes
                   -------    -----
from me to server      636    36519
from server to me     1175  1761276

看来,为了检索我的 ~1 MB 数据,我从 MySQL 服务器收到了 1.72 MB 的总网络流量。下载开销约 72%(或包括双向流量的约 76%)肯定远不及您(速率 * 时间)计算所建议的约 5900% 开销。

我强烈怀疑 MySQL Workbench 报告的 ~1 MB/s 速率并不是整个时间的整体平均传输速率。在您的特定情况下确定开销的最佳方法是使用 Wireshark 之类的工具并自行测量。

【讨论】:

  • 很公平,您的方法更有说服力。谢谢你调查它。这样看来,Workbench 的“流量”指标并没有那么有用......在一天结束时,它会显示类似于“流量 1MB/s”的内容,并且该图表在一段时间内以该速率运行(波动很小)。但这听起来并不意味着传输的总字节数 = 速率 * 时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-25
  • 2014-07-04
  • 1970-01-01
  • 1970-01-01
  • 2012-02-19
  • 1970-01-01
相关资源
最近更新 更多