Подтвердить что ты не робот

Что делает буферный параметр в сети Dapper dot?

У Dapper dot net есть параметр buffer (bool), но насколько я могу судить, единственное, что он делает, - это передать результат в список, прежде чем возвращать его.

В соответствии с документация:

По умолчанию поведение Dapper заключается в том, чтобы выполнить ваш sql и закрепить весь читатель по возвращении. Это идеально в большинстве случаев, так как это сводит к минимуму общие блокирует в db и сокращает время сети db.

Однако при выполнении огромных запросов вам может потребоваться свести к минимуму память и загружать объекты по мере необходимости. Для этого выполните буферизацию: false в метод запроса.

Я не уверен, как результат результата в списке выполняет это. Я что-то упускаю? Моя единственная идея - установить CommandBehavior для ExecuteReader в CommandBehavior.SequentialAccess (но это не так).

Спасибо, что просвещал меня.

4b9b3361

Ответ 1

но насколько я могу судить, единственное, что он делает, - это передать результат в список, прежде чем возвращать его

Вам ничего не хватает. Это ключевое различие. За исключением того, что он не является актом как таковым: фактический возвращенный объект сильно отличается. В принципе, есть два способа чтения данных:

  • в потоковом API каждый элемент предоставляется индивидуально; это очень эффективная память, но если вы делаете много последующей обработки за элемент, значит, что ваше соединение/команда может быть "активным" в течение длительного времени
  • в буферизованном API все строки считываются до того, как что-либо получится

Если вы читаете очень большой объем данных (от тысяч до миллионов строк), предпочтительным может быть небуферизованный API. В противном случае используется большая часть памяти, и может быть заметная задержка до того, как будет доступна даже первая строка. Однако в большинстве распространенных сценариев объем чтения данных находится в разумных пределах, поэтому разумно вставлять его в список, прежде чем передавать его вызывающему. Это означает, что команда /reader и т.д. Завершила до.

В качестве побочного примечания буферизованный режим также позволяет избежать так называемого "уже открытого читателя в соединении" (или что бы то ни было в точности).

Ответ 2

На практике лучше никогда не использовать buffered: false.

Я нашел чтение даже многих миллионов строк, что быстрее и эффективнее использовать память для буферизированных результатов, чем небуферизованных. Возможно, есть перекрестная точка, если ваши таблицы имеют 500 столбцов, и вы читаете 10 миллионов или 100 миллионов из нескольких строк.

Если ваши результирующие наборы меньше, чем многие миллиарды значений, по какой-либо причине не стоит использовать buffered: false.

В ходе фактического анализа я был потрясен тем, что чтение гигабайт данных с Sql Server было быстрее (на 2-6 раз быстрее) и более эффективной памяти в стандартном буферизованном режиме. Увеличение производительности даже позволяет выполнить самую последнюю возможную операцию, добавив объект в разреженный массив по индексу к массиву, который не изменяет размер. Используя многогигабайтный разреженный массив, переходящий от небуферизованного к буферизованному, улучшало время загрузки. Запись в словарь с использованием буферизации позволила добиться 6-кратного увеличения времени загрузки при вставке миллионов записей (словарь использовал таблицу int PK в качестве ключа, чтобы как можно больше использовать расчет хэш-кода).

Как и все, что касается производительности, вы всегда должны анализировать. Однако я могу сказать вам с очень высоким уровнем уверенности всегда начинать с по умолчанию буферизованного поведения Dapper.

Ответ 3

Я должен не согласиться с @chris-marisic на этом... Я столкнулся с несколькими исключениями из Out Of Memory в этой точной строке (data.ToList()) при использовании buffered: true. Это был не запрос "zillion rows X bazillion columns", а обычный SQL-результат 5-6 тыс. Строк с примерно 30 столбцами.

Это действительно зависит от вашей конфигурации. Например. независимо от того, работают ли ваши SQL и IIS на одной физической машине или нет. И сколько памяти установлено на машине IIS, и каковы настройки файла страницы и т.д. Если веб-сервер имеет 2 ГБ или меньше - рассмотрите настройку "буферизованное: ложное" для сверхтяжелых отчетов.