Адаптировать шаблон SQL «вычислить промежуточные результаты во временной таблице» к LINQ? - PullRequest
4 голосов
/ 24 ноября 2011

Моя команда создает веб-приложение на C #, которое может генерировать специальные отчеты, по-разному комбинирующие данные из одного и того же базового набора таблиц SQL Server 2008 R2.Например, одна страница «панели мониторинга» может объединять список сегодняшних продаж в каждом регионе, список наименее продаваемых товаров и их тенденций за последнюю неделю, список самых успешных продавцов и более 20 других показателей и диаграмм.,Под обложками типичная страница панели инструментов потребует не менее 30 запросов в более чем 20 различных таблицах.

К сожалению, "заморозить" эти данные и предварительно их вычислить нецелесообразно - нам нужно извлекать данные в реальном времени на лету.

Чтобы эти страницы были быстрыми,наш трюк состоял в том, чтобы идентифицировать различные запросы, которые извлекают одни и те же базовые данные.Затем мы вычисляем промежуточные результаты из этих базовых таблиц, кэшируем эти результаты во временные таблицы, а затем соединяем эту временную таблицу с другими таблицами для вычисления окончательных результатов.Используя этот подход, мы обычно можем сократить ввод-вывод и время, необходимое для конкретной панели мониторинга, в 10 раз.

Наша команда хотела бы применить этот же шаблон к аналогичной странице, которая использует LINQ-to-SQL длядоступ к данным.Нам нравится LINQ для простоты программирования, для модульного тестирования и т. Д. Но производительность снижается для описанного выше типа приложения, где мы выполняем несколько запросов, которые могут частично зависеть от одних и тех же базовых данных.

Конечно, я могу вызвать AsEnumerable(), чтобы материализовать результаты промежуточного запроса, но если промежуточные результаты велики, то получение результатов в и из SQL сводит на нет выигрыш в производительности и создает неэффективные параметризованные запросы с сотнями элементов.-long IN (@p1, ... ) предложения.

В идеальном мире LINQ-to-SQL предложит метод AsServerEnumerable(), который создаст временную таблицу промежуточных результатов, которую я мог бы повторно использовать в нисходящем направлении, не покидая БД.

Существует ли что-то подобное?

Если нет, есть какие-либо предложения о том, как сделать так, чтобы наш шаблон "промежуточной материализации на стороне сервера" хорошо работал на LINQ?

PS - я говорю "временная таблица", а не "таблица"переменная », потому что временные таблицы, как правило, лучше работают с более дорогими запросами (параллельные планы запросов, некластеризованные индексы и т. д.).Но в противном случае все вышеперечисленное применимо и к табличным переменным.

Ответы [ 2 ]

3 голосов
/ 24 ноября 2011

Нет, это не существует в необработанном LINQ и не предварительно настроено ни в одном API в стиле LINQ, о котором я знаю.

Он может существовать, если вы игнорируете часть LINQ-to-SQL "LINQ" и просто используете подход db.ExecuteQuery<T>(sql, args), но если вы делаете это, вы должны позаботиться о том, чтобы передать явное и открытое соединение с контекстом данных (если вы используете подход со строкой соединения, управление соединением обрабатывается автоматически, и вы не гарантируете получить одинаковое соединение между операциями - его можно взять из пул, и как таковой , даже если это то же базовое соединение , оно будет сброшено, удалив любые временные таблицы).

2 голосов
/ 24 ноября 2011

Что ж, если у вас много чтений, вы можете рассмотреть вопрос о создании VIEW вместо временной таблицы и добавить кластеризованный индекс в это представление.Это материализует представление в базе данных.

Индексированные представления могут использоваться SQL Server двумя различными способами.Во-первых, представление может быть вызвано непосредственно из запроса, так как в настоящее время используются обычные представления.Но вместо запуска оператора SELECT представления и создания результирующего набора представления на лету, он использует уникальный кластеризованный индекс для отображения результатов представления почти сразу.Во-вторых, любой запрос, выполняемый на SQL Server 2000/2005, автоматически оценивается на предмет наличия существующих индексированных представлений, которые бы выполняли запрос.В этом случае оптимизатор запросов использует индексированный запрос, даже если он не был указан в запросе, что значительно ускоряет его.*

...