Построение инкрементного запроса с использованием SQL Server и .NET - PullRequest
0 голосов
/ 19 августа 2010

Я работаю над проектом ASP.NET MVC, который позволяет пользователям создавать произвольно сложные запросы, одновременно добавляя предложение items.

Затем приложение генерирует соответствующий SQL, запускает его (в настоящее время использует SQL Server 2008) и отображает результаты с разбивкой, включающей количество подходящих записей для каждого добавленного элемента.

, например

UserQuery:

Имеет условие A (45)
И условиеB (33)
Или УсловиеC (55)
И условиеD (15)

Всего: 48

Проблема в том, как лучше создать и запустить SQL, чтобы получить эти результаты с учетом производительности и масштабируемости.

Первоначальная реализация построила запрос (используя подзапросы) для каждого элемента (в сочетании с предыдущим), по очереди выполняя их отдельно как скаляры. Каждое выполнение включало генерацию SQL и открытие нового SqlConnection, создание нового SqlCommand и выполнение.

Я потратил некоторое время на переписывание этого, чтобы создать один запрос (который использует CTE), чтобы вернуть одну строку с результатом каждого элемента в виде столбца.

Для этого требовалось только одно выполнение, и производительность казалась незначительной, пока запросы не стали сложными и SQL Server не начал выдавать ошибки:

Обработчику запросов не хватило внутренние ресурсы так и не смогли составить план запроса

Каков наиболее масштабируемый и эффективный способ построения и выполнения такого запроса?

Ответы [ 4 ]

2 голосов
/ 19 августа 2010

Как насчет использования LINQ?

Вы можете запустить IQueryable как прямую from t in table select t и продолжать добавлять к нему выражения (через Where), а затем позволить LINQПоставщик SQL сгенерирует запрос.Все, что вам нужно, это некоторый код для компиляции произвольных выражений ConditionA (предполагаемый текст) в эквивалентные лямбда-выражения.Это не тривиально.

Надежда состоит в том, что поставщик LINQ объединяет все выражения в одно предложение WHERE и избегает подзапросов.

В конечном счете, вы не можете иметь запрос, содержащий выражения фильтрации ad nauseamкогда-нибудь станет сложным, как бы вы это ни выражали.

0 голосов
/ 23 сентября 2010

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

Временная таблица также создается для результатов и обновляется с помощью идентификатора TempTable и количества строк для каждого по мере их заполнения.

Когда запрос обработан, результаты возвращаются путем выбора всех строк из временной таблицы результатов, которая дает полный элемент с разбивкой по элементам.

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

0 голосов
/ 19 августа 2010

Я не уверен в требованиях, стоящих за этим, но вы можете рассмотреть некоторые альтернативы.

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

Можете ли вы перейти к клиентскому решению, где вы можете использовать инфраструктуру javascript для фильтрации результатов?

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

0 голосов
/ 19 августа 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...