【问题标题】:Downloading a large table of data from a MySQL Database to text file in C#在 C# 中将大型数据表从 MySQL 数据库下载到文本文件
【发布时间】:2013-07-05 17:58:04
【问题描述】:

我有一个 MySQL 数据库“DB”,其中有一个包含单个字段的表“TABLE”,它包含大约 800 万行。我正在尝试将该表下载到文本文件中,如下所示:

//Open connection.
connection.Open();

//Create command.
MySqlCommand command = connection.CreateCommand();
command.CommandText = "SELECT * FROM `DB`.`TABLE`";

//Execute command.
MySqlDataReader result = command.ExecuteReader();

//If result isn't null
if (result != null)
{
    //Open stream to write result.
    System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Users\StackOverflow\Desktop\ID_List.txt", true);

    //For each line row of result.
    while (result.Read())
    {
        //Write result in a line.
        file.WriteLine(result.GetValue(0).ToString());
    }
}

//Close connection.
connection.Close();

运行后,它开始下载数据并将其输出到文本文件,但仅一两分钟后它就会给出:

An unhandled exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in test program.exe

Additional information: Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.

我可以改变什么或做些不同的事情来让它发挥作用?感谢您的任何建议和答案:)

[编辑]:我添加了command.CommandTimeout = 240;并测试了3次,每次下载几分钟(每次大约40MB的数据),然后才给出:

An unhandled exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in test program.exe

Additional information: Fatal error encountered during data read.

这些是调试输出的最后几行:

at MySql.Data.MySqlClient.NativeDriver.FetchDataRow(Int32 statementId, Int32 columns) in :line 0
   at MySql.Data.MySqlClient.Driver.FetchDataRow(Int32 statementId, Int32 columns) in :line 0
   at MySql.Data.MySqlClient.ResultSet.GetNextRow() in :line 0
   at MySql.Data.MySqlClient.ResultSet.NextRow(CommandBehavior behavior) in :line 0
   at MySql.Data.MySqlClient.MySqlDataReader.Read() in :line 0</ExceptionString><InnerException><ExceptionType>System.IO.EndOfStreamException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>Attempted to read past the end of the stream.</Message><StackTrace>   at MySql.Data.MySqlClient.MySqlStream.ReadFully(Stream stream, Byte[] buffer, Int32 offset, Int32 count) in :line 0
   at MySql.Data.MySqlClient.MySqlStream.LoadPacket() in :line 0</StackTrace><ExceptionString>System.IO.EndOfStreamException: Attempted to read past the end of the stream.
   at MySql.Data.MySqlClient.MySqlStream.ReadFully(Stream stream, Byte[] buffer, Int32 offset, Int32 count) in :line 0
   at MySql.Data.MySqlClient.MySqlStream.LoadPacket() in :line 0</ExceptionString></InnerException></InnerException></Exception></TraceRecord>
An unhandled exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in test program.exe
Additional information: Fatal error encountered during data read.
The program '[4548] test program.exe: Program Trace' has exited with code 0 (0x0).
The program '[4548] test program.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).

[EDIT2]:我添加了MySqlDataReader result = command.ExecuteReader(System.Data.CommandBehavior.SingleResult); 以纠正上述错误,现在我得到:

An unhandled exception of type 'MySql.Data.MySqlClient.MySqlException' occurred in test program.exe
Additional information: Query execution was interrupted

经过一些简单的谷歌搜索后,我认为是 GoDaddy 限制了查询执行时间。因此,一个可行的解决方案是使用计数器进行尝试/捕获,以跟踪在关闭连接之前检索了多少记录,并重新打开以计数器为起点的新连接,直到表大小用尽。

感谢大家的帮助!

【问题讨论】:

    标签: c# mysql timeoutexception mysql.data


    【解决方案1】:

    增加 my.ini 文件中的 wait_timeout 参数。

    http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_wait_timeout

    还有其他超时参数可能是问题所在,但我认为是那个。

    如果您无权访问您的 ini 文件,请使用“限制”来获取有限的结果集。

    首先,获取总行数(count(*)) 其次,通过 for 获得较小的结果集

     for (int i=0; i<=numberOfRowsInYourTable ; i=i+1000){
          command.CommandText = "SELECT * FROM `DB`.`TABLE` LIMIT " + i + " " + new String(i + 1000);
          // Do what you want
     }
    

    【讨论】:

    • 我无权访问服务器设置,该数据库位于 Godaddy 服务器上。
    • 处理小请求(例如 10 000 行)通常比在一个请求中获取所有内容要快。
    • 我让它尽可能多地获得,并保持一个计数器的数量;当异常发生时,我重新打开连接并从那里继续。我尝试按照您的建议使用 1k 10k 和 100k 间隔,但实际上速度较慢。尽管如此,还是感谢您的帮助。
    • 你有好的索引吗?可能是 LIMIT 的问题。
    • 可以加快速度的是只在导出结束时写入一次结果,然后使用一次写入函数,这可能很耗时(如果它的工作方式与其他语言中的 java 相同)或我更了解的php)。您填充了仅在文件末尾写入的缓冲区。
    【解决方案2】:

    将此添加到您的连接字符串:

    default command timeout=240
    

    并根据需要进行调整。

    【讨论】:

    • 您好,谢谢您,这修复了超时异常,但出现了一个新异常,请参阅原始帖子。
    • @Pi_,还有比这更多的信息吗?内部异常有什么?那个错误是没有用的。
    • 我添加了调试输出的最后几行,但除此之外我没有看到任何额外的信息。
    • @Pi_,在异常的其余部分实际上有一些真正有用的信息。 InnerException 是 Attempted to read past the end of the stream.。看看这篇关于一个 OP 如何解决这个问题的帖子。 stackoverflow.com/questions/9761499/…
    • 这是另一个可能的 SO 帖子。 stackoverflow.com/questions/6281304/…
    【解决方案3】:

    你有几个选择

    1. 您可以设置更长的超时时间 这意味着您需要在连接字符串中设置CommandTimeout parameter 集

    2. 您可以使用SELECT INTO 在服务器上生成文件

    3. 您可以使用mysqldump 实用程序,该实用程序也会在服务器上生成文件

    编辑 其他 SO 用户提到了其他类型的超时参数。我不是用户,这里的关键是哪一个

    【讨论】:

    • 如果是godaddy服务器,我不确定他能不能用mysqldump。
    猜你喜欢
    • 1970-01-01
    • 2013-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    • 2021-01-11
    • 2015-03-30
    相关资源
    最近更新 更多