这不是关于查询优化的问题。相反,这是一个关于MySQL 5.5.27(Amazon RDS)数据传输速率预期的健全性检查。
当运行一个特别重的查询时,MySQL Workbench显示数据传输速率约为1MB/s,查询运行时间约为420秒。这总共传输了约4.2亿字节的数据。
如果将这些数据保存到一个简单的文本文件中,文件的大小最终将小于7M字节。由于ResultSet的元数据、JDBC驱动程序机制等,我当然预计会看到一些开销。但对我来说,420M与7M的比例似乎非常可怕。或者,这正常吗?
非常感谢您的反馈。非常感谢!
PS。更多详细信息:
-JDBC驱动程序是mysql-connector-java-5.1.13
-数据在Amazon RDS和EC2实例之间传输
-Java 1.6 PreparedStatement用于执行查询
Wireshark是一款出色的免费开源(GPL)网络分析工具,在这种情况下可以发挥巨大作用。我运行了下面的测试,看看一个到"普通"MySQL服务器的"典型"JDBC连接可能会产生多少流量。
我在测试服务器上的MySQL(5.5.29-0ubuntu10.12.04.2)中创建了一个名为jdbctest
的表。
CREATE TABLE `jdbctest` (
`id` int(11) DEFAULT NULL,
`textcol` varchar(6) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
我用100000行表格填充了它
id textcol
------ -------
1 ABCDEF
2 ABCDEF
3 ABCDEF
...
100000 ABCDEF
在每个id
值4个字节和每个textcol
值6个字节的情况下,检索所有100000行应该表示1MB数据的某个数量级。
我启动了Wireshark,启动了一个跟踪,并运行了以下Java代码,该代码使用mysql-connector-Java-5.1.26:
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();
}
}
}
控制台输出确认我已检索到所有100000行。
查看Wireshark跟踪的摘要,我发现:
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报告的大约1MB/s的速率并不是整个时间内的总体平均传输速率。在特定情况下,确定开销的最佳方法是使用像Wireshark这样的工具并自己测量。