Использование предварительной загрузки Linq-to-SQL без объединений - PullRequest
2 голосов
/ 20 сентября 2010

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

Я работаю в предположении, что вызовы SQL являются самыми дорогими операциями.Таким образом, я стараюсь минимизировать их количество, но стараюсь избегать сумасшедших сложных запросов, которые сложно оптимизировать.

Пример: я использую DataLoadOptions с моим DataContext - его цельзаключается в минимизации количества запросов путем предварительной загрузки связанных объектов.(Ака, жадная загрузка против ленивой загрузки.)

Проблема: Linq использует соединения для достижения цели.Как и во всем, это компромисс.Я получаю меньше запросов, но эти соединенные запросы являются более сложными и дорогими.Если вы зайдете в SQL Profiler, это станет ясно.

Итак, я бы хотел, чтобы в Linq была включена опция preload без объединений .Это возможно?Вот как это может выглядеть:

У меня есть таблица Persons, таблица Items и таблица PersonItems, чтобы обеспечить связь «многие ко многим».При загрузке коллекции Person, я бы хотел, чтобы все их PersonItems и Предметы также загружались.

В настоящее время Linq делает это с помощью одного большого запроса, содержащего два объединения.Я бы предпочел, чтобы это были три запроса, не связанные с присоединением: один для Persons, один для всех PersonItems, относящихся к этим Persons, и один для всех Предметов, относящихся к этим PersonItems.Затем Linq автоматически организует их в связанные объекты.

Каждый из них будет быстрым запросом типа пожарного шланга.В долгосрочной перспективе это позволило бы обеспечить предсказуемую производительность в масштабе сети.

Вы когда-нибудь видели, чтобы это было сделано?

1 Ответ

0 голосов
/ 14 марта 2011

Я полагаю, что то, что вы описываете при выполнении трех запросов, не связанных с присоединением, - это, по сути, то, что происходит внутри, когда выполняется один запрос на присоединение.Я могу ошибаться, но в этом случае отдельный запрос будет более эффективным, поскольку задействован только один запрос к базе данных, а не три.Если у вас есть проблемы с производительностью, я бы удостоверился, что столбцы, к которым вы присоединяетесь, проиндексированы (вы не должны видеть сканов таблиц в профилировщике SQL).Если этого недостаточно, вы можете написать пользовательскую хранимую процедуру, чтобы получить только нужные данные (при условии, что вам не нужны все столбцы каждого объекта, это позволит вам использовать поиск индекса, который выполняется быстрее, чем сканирование индекса),или, альтернативно, вы можете денормализовать (дублировать данные в таблицах), чтобы вообще не происходило объединение.

...