Почему AsSplitQuery выполняет отдельный обмен данными с БД для каждого запроса?
Наконец-то мне удалось обновить очень старую кодовую базу с EF6 до EF Core 7, и я играю с некоторыми «новыми» функциями.
Я был очень взволнован опцией Split query для быстрой загрузки, но при чтении документации меня вернуло это:
Каждый запрос в настоящее время подразумевает дополнительный сетевой обмен данными с вашей базой данных. Многократные обращения по сети могут снизить производительность, особенно при высокой задержке в базе данных (например, в облачных службах).
Почему? Почему это не несколько запросов за один цикл?SqlDataReader
может обрабатывать запросы с несколькими наборами результатов. Это помешало мне переписать существующий код с использованием хранимой процедуры в EF.
Если только эти разделенные запросы не выполняются одновременно, когда MARS включен при подключении к серверу SQL. Они? я знаю этоDbContext
не поддерживает параллельную обработку, но выполняет ли он эти запросы одновременно и обрабатывает результаты только последовательно?
Дополнительный вопрос: если существует это ограничение для выполнения каждого запроса в отдельном круговом обходе, возможно ли определить поведение SplitQuery только для определенных включений в запрос вместо определения его для всех включений в запрос?
1 ответ
Основываясь на некотором обсуждении на github, если MARS включен, EF Core может использовать его для разделенных запросов (см. this и this), но в общем случае (поскольку EF Core может использоваться с разными базами данных) следующая цитата из документов я бы сказал объясняет общее поведение/формулировку случая:
В то время как некоторые базы данных позволяют использовать результаты нескольких запросов одновременно (SQL Server с MARS, Sqlite), большинство из них позволяют активировать только один запрос в любой момент времени. Таким образом, все результаты более ранних запросов должны буферизоваться в памяти вашего приложения перед выполнением более поздних запросов, что приводит к увеличению требований к памяти.
Также может быть полезен следующий комментарий Шая Рожански (одного из членов команды EF):
Известно, что поддержка MARS в SqlClient имеет различные проблемы с производительностью (а также другие ошибки), некоторые из них серьезные. Рекомендуется избегать этого.