2010-11-30 18 views
9

Tengo un problema con el tiempo de espera de un script mientras obtengo datos de una consulta en una tabla grande.Tiempo de espera de conexión en la consulta en la tabla grande

La tabla tiene 9,521,457 filas.

La consulta que estoy tratando de preformas es:

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

Esta consulta se ejecuta sin problemas en HeidiSQL y toma de 171 segundos y devuelve 434 filas.

Pero cuando ejecuto mi secuencia de comandos C# lo agoto el tiempo de espera después de 161 filas.

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. 

Este es el código

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

Respuesta

22
command.CommandTimeout = int.MaxValue; 

Si usted sabe más exactamente qué número para insertar, hacer eso. Si lo configura en int.MaxValue, está eliminando una barrera de seguridad.

12

Ajuste el CommandTimeout en el objeto de comando

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; no funcionó :(aún se agotó el tiempo de espera – Androme

+1

@DoomStone Su base de datos puede tener un tiempo de espera definido, cuando solicita el tiempo de espera usando commandTimeout esto puede ser reemplazado por la configuración de la base de datos. En mi caso, funcionó, pero en su caso podría ser un problema que necesita resolver con su DBA .. (para lectores futuros ... obviamente su problema fue hace años lo siento) – Chris

2

Agregue un índice en la columna customerId.

+0

¡Hay, es la clave principal! – Androme

+1

@DoomStone - No veo cómo puede posiblemente tomar 171 segundos para devolver 434 filas a continuación. ¿Está devolviendo datos extremadamente amplios (por ejemplo, BLOB) y 'CustomerId' no puede ser el PK en sí mismo de todos modos si 3 clientes devuelven 434 filas. ¿Cuáles son las otras columnas en el índice y qué es el orden de estas columnas en el índice compuesto? –

+1

¿Quisiste decir que esta era la clave principal para otra tabla? Si fuera la clave principal en esta tabla, entonces no deberías obtener 434 filas devueltas de tu consulta. – whudson05

0
command.CommandTimeout = 2147483; 

El valor más grande para un tiempo de espera de comandos de MySQL es el mayor valor para un entero de 32 bits, en milisegundos, 2147483647. Sin embargo, en C# la propiedad CommandTimeout está en segundos, no en milisegundos, por lo que cualquier mayor que 2.147.483 se traducirá en una excepción

Aunque esto no es infinito, son 24 días, 20 horas, 31 minutos y 23 segundos, lo que esperamos satisfaga sus necesidades.

Establecer el valor en 0 no me funcionó. La propiedad CommandTimeout no retendría el valor 0 y mantuvo el autocambio de nuevo a 30.

Establecer el valor en -1 parecía funcionar, pero no lo probé lo suficiente como para estar seguro de que un tiempo de espera nunca ocurrir.

Opción más segura: ir con 2147483.

Cuestiones relacionadas