查询大表时的连接超时

时间:2010-11-30 15:58:11

标签: c# mysql timeout

从大型表格查询中获取数据时,我遇到了脚本超时的问题。

该表有9,521,457行。

我正在尝试进行的查询是:

SELECT * 
FROM `dialhistory` 
WHERE `customerId` IN (22606536, 22707251, 41598836);

此查询在HeidiSQL上运行没有问题,大约需要171秒并返回434行。

但是当我运行我的C#脚本时,它会在161行之后超时。

16:54:55: Row 1
...
16:54:55: Row 161
16:55:32: Error -> Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.

这是代码

public MySqlDatabase(string server, string database, string username, string password)
{
    ConnectionString = "SERVER=" + server + ";DATABASE=" + database + ";UID=" + username + ";PASSWORD=" + password + ";";

}

public IQueryable<DailHistory> GetHistory(IList<int> customerIds)
{
    IList<DailHistory> list = new List<DailHistory>();
    var connection = new MySqlConnection(ConnectionString);
    connection.Open();
    var command = connection.CreateCommand();
    command.CommandText = "SELECT * FROM `dialhistory` WHERE `customerId` in ("+string.Join(",", customerIds.ToArray())+")";
    var reader = command.ExecuteReader();
    int i = 1;
    while (reader.Read())
    {
        Console.WriteLine(DateTime.Now.ToLongTimeString() + ": Row " + i);
        i++;
        try
        {
            var d = new DailHistory();
            d.CustomerId = int.Parse((string) reader["customerId"]);
            d.Agent = ParseNullAbleString(reader["agent"].ToString());
            d.CallBackReason = ParseNullAbleString(reader["callBackReason"].ToString());
            d.CallState = ParseCallSate(reader["callState"].ToString());
            d.ContactResponse = ParseNullAbleString(reader["contactResponse"].ToString());
            d.DailTime = new DailTime(reader["dialStart"].ToString(), reader["dialEnd"].ToString());
            d.HistoryIndex = int.Parse(reader["historyIndex"].ToString());
            d.Note = ParseNullAbleString(reader["note"].ToString());
            d.OldDialNo = ParseNullAbleInt(reader["oldDialNo"].ToString());
            d.ProjectJob = ParseNullAbleString(reader["projectJob"].ToString());
            list.Add(d);
        }
        catch(Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
    reader.Close();
    return list.AsQueryable();
}

4 个答案:

答案 0 :(得分:28)

command.CommandTimeout = int.MaxValue;

如果您准确了解要插入的号码,请执行此操作。如果将其设置为int.MaxValue,则表示您正在删除安全屏障。

答案 1 :(得分:11)

在命令对象

上设置CommandTimeout
var command = connection.CreateCommand();
command.CommandTimeout = 0;
//zero specifies never timeout. 
//Any number greater than zero is the number of seconds before 
//the command will time out.

答案 2 :(得分:2)

customerId列上添加索引。

答案 3 :(得分:0)

command.CommandTimeout = 2147483;

有一个MySQL命令超时的最大值是一个32位整数的最大值,以毫秒为单位,2147483647但在C#CommandTimeout属性是以秒,不毫秒,所以任何高于2147483会导致异常。

虽然这不是无限的,但它是24天,20小时,31分钟和23秒,这有望满足您的需求。

将值设置为0对我不起作用。 CommandTimeout属性不会保留值0并保持自动更改回30。

将值设置为-1似乎确实有效,但我没有对其进行足够的测试以确定永远不会发生超时。

最安全的选择:选择2147483。