我有一个简单的查询返回25,026行:
MySqlCommand cmd = new MySqlCommand("SELECT ID FROM People", DB);
MySqlDataReader reader = cmd.ExecuteReader();
Run Code Online (Sandbox Code Playgroud)
(ID是一个int.)如果我这样做:
int i = 0;
while (reader.Read()) i++;
Run Code Online (Sandbox Code Playgroud)
i将等于25026.但是,我需要对循环中的每个ID进行一些处理; 每次迭代最终都会在数百毫秒内完成.
int i = 0;
MySqlCommand updater = new MySqlCommand("INSERT INTO OtherTable (...)", anotherConnection);
updater.Prepare();
while (reader.Read()) {
int id = reader.getInt32(0);
// do stuff, then
updater.ExecuteNonQuery();
i++;
}
Run Code Online (Sandbox Code Playgroud)
但是,在处理大约4:15之后,reader.Read()只返回false.在我的大多数测试运行中,i等于14896,但它有时也停在11920. DataReader在相同数量的记录之后退出是可疑的,并且在不同行数之后它停止的时间似乎更奇怪.
为什么reader.Read()在肯定有更多行时返回false?没有例外被抛出 - 甚至没有第一次机会异常.
更新:我在回答Shaun的回答中提到我确信MySqlDataReader.Read()吞下异常,所以我下载了Connector/Net的源代码(bzr branch lp:connectornet/6.2 C:/local/path)并将项目添加到我的解决方案中.果然,经过6:15的处理,一个例外!
resultSet.NextRow()抛出MySqlException"从流中读取"消息的调用已失败.这InnerException是一个SocketException:
{ Message: "An existing connection was forcibly closed by the remote host",
ErrorCode: 10054,
SocketErrorCode: ConnectionReset }
Run Code Online (Sandbox Code Playgroud)
10054表示TCP套接字用中止RST,而不是正常断开握手(FIN,FIN ACK,ACK),它告诉我的东西扭曲正在发生的网络连接.
在my.ini中,我曲柄interactive_timeout并且wait_timeout到1814400(秒)无济于事.
那么......为什么我的连接在阅读6:15(375秒)后被拆除了?
(另外,为什么当我使用官方二进制文件时,这个异常会被吞噬?它看起来应该冒泡到我的应用程序代码.)
由于我只是读取ints,因此我最终只是将整个结果集读入 a List<int>,关闭读取器,然后进行处理。这对于 s 来说很好int,因为即使一百万占用 < 100 MB 的 RAM,但我仍然对根本问题没有解决感到失望 - 如果我每行读取超过一个int,内存将变得非常大大数据集的问题。
| 归档时间: |
|
| 查看次数: |
5184 次 |
| 最近记录: |