查询大表时的连接超时

在从大型表上查询数据时,我遇到了脚本超时的问题。

该表有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 GetHistory(IList customerIds) { IList list = new List(); 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(); } 

 command.CommandTimeout = int.MaxValue; 

如果您更准确地知道要插入的数字,请执行此操作。 如果将其设置为int.MaxValue ,则表示您正在删除安全屏障。

在命令对象上设置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. 

customerId列上添加索引。

 command.CommandTimeout = 2147483; 

MySQL命令超时的最大值是32位整数的最大值,以毫秒为单位,2147483647.但在C#中,CommandTimeout属性以秒为单位,而不是毫秒,因此任何高于2147483的值都将导致exception。

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

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

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

最安全的选择:选择2147483。