Действительно странная проблема производительности DataReader - PullRequest
3 голосов
/ 17 ноября 2011

У меня есть база данных SQL Server, и я использую ADO.NET ExecuteReader для получения устройства чтения данных. Моя хранимая процедура возвращает около 35 000 записей.

Вызов ExecuteReader занимает примерно 3 секунды, чтобы вернуть устройство чтения данных.

Я использую код, очень похожий на этот, чтобы получить мои предметы.

using(var conn = new SqlConnection(MySQLHelper.ConnectionString)) {
    conn.Open();
    var sqlCommand = SqlHelper.CreateCommand(conn, "spGetItems");
    using (var dr = sqlCommand.ExecuteReader()) {
        while(dr.read){
            var item = new Item{ID = dr.GetInt32(0), ItemName = dr.GetString(1)};
            items.Add(item);
        }
    }
 } 

Большинство операций чтения занимает 0 миллисекунд. Тем не менее, периодически я получаю чтение, которое занимает около 5,5 секунд (5000+ миллисекунд). Я посмотрел на данные и не смог найти ничего необычного. Я думаю начал смотреть на частоту записей, которые занимали так много времени.

Это было интересно. Хотя они не были полностью последовательными, они были близки. Записи, которые долго загружались, были следующими ...

Запись №: 29, 26, 26, 27, 27, 29, 30, 28, 27, 27, 30, 30, 26, 27

Похоже, что от 26 до 30 записей будет считываться от 0 до нескольких миллисекунд, а затем это займет 5 секунд, а затем следующие 26-30 записей снова будут считаны, как и ожидалось.

Я в полной растерянности. Я могу опубликовать больше кода, но там не так много. Это довольно простой код.

EDIT Ни одно из моих полей не является varchar (max) или даже близко. Мое самое большое поле числовое (28,12).

После изменения моей хранимой процедуры у меня больше не возникает проблем. Сначала я изменил его на Select TOP 100, затем поднял его до Top 1000, затем до 10000, а затем до 100000. У меня никогда не было проблемы с этим. Затем я удалился в ТОП, и теперь у меня нет проблемы, которой я был раньше.

Ответы [ 4 ]

3 голосов
/ 17 ноября 2011

SqlDataReader буферизует результаты, отправленные клиенту. Подробнее см. на этой странице в MSDN :

Когда результаты отправляются обратно клиенту, SQL Server помещает в каждый пакет столько строк набора результатов, сколько может, сводя к минимуму количество пакетов, отправляемых клиенту.

Я подозреваю, что вы получаете 26-30 записей на пакет. Когда вы просматриваете записи, вы получаете задержку при загрузке новых записей.

1 голос
/ 27 марта 2012

У меня была похожая проблема.Ответ состоял в том, чтобы привести все текстовые поля, используя nvarchar (max), а затем .NET ExecuteReader, возвращенный в течение того же периода, что и exec sproc в MS Studio.Обратите внимание, что sproc не содержал транзакций, но вызов .NET был включен в транзакцию.

0 голосов
/ 17 ноября 2011

Сколько времени занимает запуск хранимой процедуры без вашей программы?Я подозреваю, что это просто занимает много времени, и вы видите странное поведение из-за буферизации, как отмечали другие.

0 голосов
/ 17 ноября 2011

Из какой структуры таблицы вы читаете?Разве вы не используете тип nvarchar (max) для второго столбца?

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