metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2010-07-02 07:04 am

Как же удолбут.

Тема "сессий" и "транзакций" при подключениях к различным базам данных судя по всему является очередным потаенным вуду для разработчиков. Причем даже для разработчиков самих БД и драйверов доступа к ним.

Иначе я не могу объяснить тот факт, что в некоторых серверах невозможно открыть одновременно две транзакции в одном соединении. Или то, что из трех ADO.NET провайдеров (Firebird, MSSQL, Postgresql) одновременно открыть два SQL запроса в одном соединении и читать одновременно из них - можно только в Firebird, два остальных ругаются типа "уже открыт DataReader".

Ну вот вопрос как в ADO.NET ленивым образом (не загружая в память) прочитать список сущностей из БД, и для каждой сущности прочитать вложенные для нее?
Ну всегда обычное решение было - цикл по одному DataReader, из него берем некое поле, подсовываем его значение в параметр второй команде, выполняем ExecuteReader и пытаемся читать во вложенном цикле. В Firebird работает, в других хрен.

PS: В Npgsql есть параметр PreloadReader=true, который позволяет обойти это ограничение и который не рекомендуется использовать, т.к. он грузит весь DataReader в память и смысл ленивой итерации теряется. И написано, что это ограничение - by design, упомянуто в доке на ADO.NET.

По моему, архитекторов ADO.NET надо убить, это же идиотизм клинический.

[identity profile] norguhtar.livejournal.com 2010-07-02 10:13 am (UTC)(link)
Кстати да. Я тут подумал. А что мешает использовать join запрос?

[identity profile] metaclass.livejournal.com 2010-07-02 10:20 am (UTC)(link)
И что это будет? Денормализованный датасет типа "на каждую запись в детализации (коих over 9000) повторяем запись-владелец"?

[identity profile] norguhtar.livejournal.com 2010-07-02 10:27 am (UTC)(link)
Да. А дальше обрабатываем. В чем собственно проблема? В том что с этим не удобно работать?

[identity profile] metaclass.livejournal.com 2010-07-02 10:29 am (UTC)(link)
В том что это маразм, очевиднейший. Сначала делаем декартово произведение, денормализуем, сосем по не самому быстрому каналу на клиента увеличенный по сравнению с нужным результат, а потом его нормализуем обратно, закатывая солнце вручную.
Проще уж на сервере все обработать тогда, ничего на клиента/миддлварь не вытаскивая.

[identity profile] norguhtar.livejournal.com 2010-07-02 11:47 am (UTC)(link)
Если у вас обрабатываются все данные это самый быстрый способ их получить и обработать. Если выборочно относительно того какие данные в первой таблице, то можно делать отдельный ленивый select. Опять же никто offset и limit не отменял.

[identity profile] vp.livejournal.com 2010-07-02 10:37 am (UTC)(link)
Не, это явный перебор.
Приемлемо ТОЛЬКО в случае, когда ну вообще никаких средств не осталось..

[identity profile] norguhtar.livejournal.com 2010-07-02 11:53 am (UTC)(link)
Если вы обрабатываете данные в обоих таблицах это самый правильный и быстрый вариант для получения данных. Если вы обрабатываете выборочно данные во второй подчиненной таблице, то можно использовать запросы. Иначе у вас будет пиздец-пиздец по производительности. Как раз из-за перманентного дерганья второй таблицы.

[identity profile] metaclass.livejournal.com 2010-07-02 11:58 am (UTC)(link)
Пиздец-пиздец будет только в кривых серверах, которые не умеют запросы препарить и держать отпрепаренными. Таблица по всякому будет в кэше сервера, если запрос не закрывать каждый раз - оно летает, проверено.
Другое дело что, судя по всему, ADO.NET это корректно делать не умеет, т.к. затачивалась под кривые сервера, коих большинство.

[identity profile] norguhtar.livejournal.com 2010-07-02 12:29 pm (UTC)(link)
Вообще время работы первого запроса будет ниже чем суммарное время второго. Вообщем как делать сильно зависит от того что делать. Ну и к слову JPA умеет из join который я привел разворачивать два объекта, так что с точки зрения удобства тут все в порядке.

[identity profile] vp.livejournal.com 2010-07-02 03:32 pm (UTC)(link)
ADO ж вообще задумывался как обобщенный интерфейс к БД. Вот скорее всего они и привели его к наименьшему общему знаменателю, выкинув такого рода фичи серверов, которые не обобщаются.