Тайм-аут соединения по запросу на большой таблице - PullRequest
12 голосов
/ 30 ноября 2010

У меня проблема с тайм-аутом сценария при получении данных из запроса большой таблицы.

Таблица содержит 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 ]

29 голосов
/ 30 ноября 2010
command.CommandTimeout = int.MaxValue;

Если вы точно знаете, какой номер вставить, сделайте это.Если вы установите его на int.MaxValue, вы удалите защитный барьер.

11 голосов
/ 30 ноября 2010

Установите 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 голосов
/ 30 ноября 2010

Добавить индекс для столбца customerId.

0 голосов
/ 07 декабря 2017
command.CommandTimeout = 2147483;

Наибольшее значение для тайм-аута команды MySQL - это наибольшее значение для 32-битного целого числа в миллисекундах, 2147483647. Но в C # свойство CommandTimeout указывается в секундах, а не в миллисекундах, поэтому любое значение больше 2147483 приведетисключение.

Хотя это не бесконечно, это 24 дня, 20 часов, 31 минута и 23 секунды, которые, мы надеемся, будут соответствовать вашим потребностям.

Установка значения 0 неработать на меня.Свойство CommandTimeout не будет сохранять значение 0 и автоматически изменяет значение обратно на 30.

Установка значения -1 действительно работает, но я не проверял его достаточно, чтобы убедиться, что тайм-аутникогда не произойдет.

Самый безопасный вариант: перейти с 2147483.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...