2009-02-07 1 views
0

Я работаю с третьим приложением pary, где я не могу изменить таблицы. Мы создали пользовательские таблицы соответствия «Ежемесячно» с дополнительным столбцом datetime «AsOfDate», где мы выгружаем данные в конце месяца и помещаем эти данные в дату последнего дня месяца.Объединить или использовать логику управления потоком, чтобы определить, какая таблица будет отображаться на

Я хочу, чтобы иметь возможность создать единую хранимую процедуру (приложение спроектировано так, чтобы требовать представления или хранимой процедуры в качестве источника всех отчетов.) И использовать параметр, который будет либо использовать текущую таблицу данных (параметр может быть NULL или = Today's Date) или используйте таблицу конца месяца и фильтр к концу месяца. Таким образом, у меня есть один отчет, в котором пользователь может либо использовать текущий, либо данные с определенного периода окончания месяца.

Что бы вы предпочли (И почему) К сожалению, это не полностью закодирована

Решение # 1 Union Query

Create Proc Balance_Report (@AsOfDate) 
AS 

Select Column1 
From 
    (Select GetDate() as AsOfDate 
     , Column1 
    From Current.Balance 
    Union 
    Select AsOfDate 
     , Column1 From MonthEnd.Balance 
    ) AS All_Balances 
Where All_Balances.AsOfDate = @AsOfDate 

Решение # 2 Используйте Если заявление, чтобы выбрать таблицу

Create Proc Balance_Report (@AsOfDate) 
AS 

If @AsOfDate IS NULL or @AsOfDate = GetDate() 
    Select GetDate() as AsOfDate 
     , Column1 
    From Current.Balance 
Else 
    Select AsOfDate 
     , Column1 From MonthEnd.Balance 
    Where AsOfDate = @AsOfDate 

Опять же, это не полностью закодировано и является своего рода агностиком db (но это SQL Server 2005).

Edit: Вариация для решения # 2, используя отдельные хранимые процедуры

Create Proc Balance_Report (@AsOfDate) 
AS 

If @AsOfDate IS NULL or @AsOfDate = GetDate() 
    Exec Current_Balance_Date -- no param necessary 
Else 
    exec MonthEnd_Balance_Date @AsOfDate 

ответ

1

Как у вас есть вещи, второй метод, вероятно, будет быстрее. Если бы вы использовали секционированный вид, вы могли бы установить ограничения таким образом, чтобы оптимизированный знал, чтобы игнорировать одну или несколько таблиц в элементе select, и вы получите такую ​​же производительность. Это также позволило бы сохранить всю вашу логику в одном утверждении, а не синхронизировать два оператора. Это может быть или не быть проблемой для вас, исходя из того, насколько сложна инструкция SELECT.

Следует помнить, что если вы используете второй метод, обязательно отметьте сохраненную процедуру как WITH (RECOMPILE) (я не могу вспомнить, нужны ли скобки или нет - проверьте синтаксис). Таким образом, оптимизатор создаст новый план запросов, на основе которого должна выполняться ветвь оператора IF.

+0

Если бы я заменил свои запросы двумя отдельными sprocs, мне все равно понадобилась бы перекомпиляция? У меня нет ничего против RECOMPILE; Мне было просто любопытно. – JeffO

+1

Если вы использовали две отдельные хранимые процедуры, вам потребуется только перекомпиляция, если параметры повлияют на лучший план, который будет использоваться. –

1

Я предпочитаю несоюзных решение. Выбор из одной таблицы всегда будет быстрее, чем объединение и выбор данных из одной таблицы из объединения.

+0

Я думаю, что это снизится до производительности для пользователей, которые обычно смотрят на текущие данные. Я не знаю, нужна ли мне версия этого, которая будет включать более одного периода и может включать в себя текущий, но это не вопрос. – JeffO

+0

Добавление одного параметра If/Else не повлияет на вашу производительность любым способом, сопоставимым с выполнением операции UNION. Используйте отдельную процедуру, если вам нужно выбрать кратные - и да, вам нужно будет сделать UNION там. – tvanfosson

Смежные вопросы