2010-09-19 1 views
2

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

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

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

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

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

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

Linq в настоящее время делает это с одним большим запросом, содержащим два соединения. То, что я предпочел, это три запроса без присоединения: один для Лица, один для всех PersonItems, относящихся к этим Лицам, и один для всех предметов, относящихся к этим PersonItems. Тогда Linq автоматически уложил бы их в связанные объекты.

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

Когда-либо видел это?

+2

Недостаточно для ответа, но я думаю, я просто задаюсь вопросом, почему у вас, кажется, есть отрицательная реакция на объединение, не имея профилированных, чтобы увидеть, действительно ли они хуже на производительности. С другой стороны, кто-то может указать, что выполнение нескольких запросов, когда одно соединение - с соответствующими внешними ключами на месте - может делать то же самое или лучше. И, в конце концов, код, скорее всего, тоже станет проще. –

+0

Справедливо, хотя я вижу сложность как прокси для производительности. На данный момент он отлично работает, но кажется, что объединения должны быть несколько экспоненциальными с точки зрения расхода - умножения строк x строк на одно соединение. Это также различие между производительностью и масштабами. Масштаб - это когда производительность предсказуема, т. Е. Линейна. –

ответ

0

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