从大型表格查询中获取数据时,我遇到了脚本超时的问题。
该表有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();
}
答案 0 :(得分:28)
command.CommandTimeout = int.MaxValue;
如果您准确了解要插入的号码,请执行此操作。如果将其设置为int.MaxValue
,则表示您正在删除安全屏障。
答案 1 :(得分:11)
在命令对象
上设置CommandTimeoutvar 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。