2010-11-30 18 views
9

從大型表上提取數據時,腳本超時出現問題。在大型表上查詢時的連接超時

該表有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(); 
} 

回答

22
command.CommandTimeout = int.MaxValue; 

如果你知道更準確地插入哪個號碼,這樣做的。如果將其設置爲int.MaxValue,則表明您正在刪除安全屏障。

12

設置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. 
+0

command.CommandTimeout = 0;沒有工作:(它仍然超時 – Androme 2010-11-30 16:20:59

+1

@DoomStone你的數據庫可以有一個超時定義,當你請求超時使用commandTimeout這可以被數據庫配置覆蓋。在我的情況下它適用於我,但在你的情況下,它可能是一個問題,你需要與你的DBA解決..(對於未來的讀者..顯然你的問題是幾年前對不起) – Chris 2013-12-18 19:50:09

2

customerId列中添加索引。

0
command.CommandTimeout = 2147483; 

用於MySQL命令超時的最大值是一個32位整數的最大值,以毫秒爲單位,2147483647但在C#CommandTimeout屬性是以秒,不毫秒,所以任何高於2147483將導致在例外。

雖然這不是無限的,但它是24天,20小時,31分鐘和23秒,這將有望滿足您的需求。

將該值設置爲0對我無效。 CommandTimeout屬性不會保留0的值並保持自動更改爲30.

將該值設置爲-1似乎工作,但我沒有測試它足以確定超時將永遠不會發生。

最安全的選項:配合2147483.