Re[36]: Entity Framework за! и против!
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.07.14 21:27
Оценка:
Здравствуйте, Alexander Polyakov, Вы писали:

G>>Не понял, как проекция пропушится во все подзапросы?

AP>Чего? Нормально условие задачи сформулировать можешь?
Еще раз: сгенери сложный запрос с помощью linq, сделай .select с проекцией и увидишь, что проекции попали во все подзапросы.


G>>>>Даже если в подзапросе группировка, которую sql сам не соптимизирует.

AP>>>Proof link в студию или ты опять сочиняешь.
G>>Так попробуй сам сделать.
AP>Как же я сделаю то, чего нет? Короче, слив засчитан.
Да просто на SQL напиши запрос с подзапросом, в котором есть группировка и посмотри план.
Примерно так:

select field1 from (select field1, field2,... from table group by field1, field2,...)


SQL Server в этом случае сам не протакливает проекции в позапросы, а честно выполнит все вычисления с затягиванием данных с диска, даже если это совсем неоптимально.


AP>>>В СУБД движок, который перезаписывает запрос и генерирует план его выполнения, гораздо круче любого LINQ провайдера. И СУБД честно отводит на это ощутимое время, а потом использует кэш. Тут важно то, что ключом в кэше является сама строка запроса. А у LINQ провайдера ключа подходящего нет.

G>>При чем тут это?
AP>>>Кстати, то, что СУБД не оптимизирует вот такое "... = @p1 OR @p1 IS NULL" связанно именно с кэшем планов. Либо надо бегать по дереву и тогда теряем в производительности кэша, либо отдать это на откуп пользователю, пусть он генерирует разные тексты для запросов, которые будут разными ключами в кэше.
G>>Да, и linq тут спасает. Хоть и "ключа поодходящего нет" (с)
AP>Это "спасение" за счет уменьшения производительности кэша.
Это же лучше, чем уменьшение производительности запроса. Если запросов много, то планы из кеша не будут вытеснены, а если мало, то пофиг.

AP>Разработчики СУБД давно бы сделали это, но не считаю, что это стоит потерь производительности кэша.

Разработчики СУБД рассчитывают на то, что разработчики приложений будут писать запросы со стабильными планами. Дополнительный анализ стабильности плана может дорого стоить.
Но люди это люди, и они стремятся сократит затраты на разработку и поддержку, поэтому пишут запросы общего вида, что ведет к снижению эффективности.
Кстати Oracle умеет определять такие проблемы с планами и генерирует разные планы автоматом.

AP>А изготовители LINQ провайдеров вынуждены хотя бы таким кэшем прикрывать уж совсем неприличные тормоза (на неприлично простой задаче по генерации текста).

Какие неприличные тормоза? 0,4 мс на запрос, это меньше статистической погрешности от общего времени выполнения запроса.

Твое решение тратит гораздо больше времени в процессе написания, причем время программистов на 3 порядка дороже, чем время железки.

G>>Именно, и проекции попапил в том числе в подзапросы. Как склейкой строк такое повторить?

AP>Выше уже приводил код.
Ты не понял. Вот есть Linq запрос, который генерирует sql такого вида:

select field1, field2,... from (select field1, field2,... from t where...)


Потом выполняется .Select(e => e.field1) и результирующий SQL получается такой:

select field1 from (select field1 from t where...)


Рассчитывать что сам SQL Server такое соптимизирует нельзя.

Вот и как это сделать склейкой строк?


G>>Ты чего курил? В этой теме уже раз 100 приводили декомпозицию IQueryable, хоть комбинаторами (в том числе обобщенными), хоть руками деревья выражений пиши, хоть dlinq (который используется в новых веб-формах для фильтров и сортировок).

AP>100-ый раз повторяю, Хейлсберг не разрабатывал LINQ для построения запросов. А у вас доступа к компилятору нет, поэтому ваши решения либо сводят всю идею linq-а на нет, либо убогие частные случаи.
Если повторить чушь 100 раз она правдой не ставит.
Кстати Linq делал не Хейлсберг, а Мейер. Он подобное еще в 90-х делал на хаскеле, именно с прицелом на построение SQL запросов из кода (внезапно).
Доступ к компилятору для генерации деревьев выражений не нужен. Компилятор только преобразует лябмды в Expression Tree. Никто тебе не мешает любое дерево выражений собрать руками и обработать его как захочешь. Примеры кода тебе уже приводили раз десять, которые по объему и скорости работы сильно выигрывают у твоего решения.

Причем как бы ты не старался, все равно бегать по деревьям ET оказывается быстрее, чем ковырять IL, а потом выполнять реальные запросы к базе. Да и качество генерируемого SQL у Linq повыше, чем у самописных запросов (а учитывая время, затраченное на написание — гораздо выше). Linq может сгенерировать столько вариантов запроса, сколько руками замучаешься писать и поддерживать, даже имея удобный механизм для склейки строк.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.