Использование с vs объявить временную таблицу: производительность / разница? - PullRequest
14 голосов
/ 25 марта 2011

Я создал функцию sql в SQLServer 2008 , которая объявила временную таблицу и использует ее для вычисления скользящего среднего по значениям внутри

declare @tempTable table 
    (
        GeogType nvarchar(5),
        GeogValue nvarchar(7),
        dtAdmission date,
        timeInterval int,
        fromTime nvarchar(5),
        toTime nvarchar(5),
        EDSyndromeID tinyint,
        nVisits int
    )
insert @tempTable select * from aces.dbo.fEDVisitCounts(@geogType, @hospID,DATEADD(DD,-@windowDays + 1,@fromDate),
                @toDate,@minAge,@maxAge,@gender,@nIntervalsPerDay, @nSyndromeID)


    INSERT @table (dtAdmission,EDSyndromeID, MovingAvg) 
    SELECT list.dtadmission
        , @nSyndromeID
        , AVG(data.nVisits) as MovingAvg
    from @tempTable as list 
        inner join @tempTable as data  
    ON list.dtAdmission between data.dtAdmission and DATEADD(DD,@windowDays - 1,data.dtAdmission) 
    where list.dtAdmission >= @fromDate
    GROUP BY list.dtAdmission

, но также обнаружила, чтоВы можете объявить tempTable следующим образом:

with tempTable as 
(
    select * from aces.dbo.fEDVisitCounts('ALL', null,DATEADD(DD,-7,'01-09-2010'),
        '04-09-2010',0,130,null,1, 0)
)

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

Iтакже нашел create temporary table @table отсюда Как объявить внутреннюю таблицу в MySQL? , но я не хочу, чтобы таблица сохранялась вне функции (я не уверен, что это создает временная таблица создания илинет.)

Ответы [ 3 ]

27 голосов
/ 25 марта 2011

Синтаксис @table создает переменную таблицы (фактическую таблицу в tempdb) и материализует результаты к ней.

Синтаксис WITH определяет Общее табличное выражение , которое не материализовано и является просто встроенным представлением.

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

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

В этом случае у вас (в общем) есть 3 варианта.A @tablevariable, #localtemp стол и ##globaltemp стол.Однако только первый из них разрешен для использования внутри функции.

Дополнительную информацию о различиях между табличными переменными и таблицами #temp см. Здесь .

10 голосов
/ 25 марта 2011

В дополнение к тому, что ответил Мартин,

;with tempTable as 
(
    select * from aces.dbo.fEDVisitCounts('ALL', null,DATEADD(DD,-7,'01-09-2010'),
        '04-09-2010',0,130,null,1, 0)
)

SELECT * FROM tempTable

также можно написать так:

SELECT * FROM 
(
    select * from aces.dbo.fEDVisitCounts('ALL', null,DATEADD(DD,-7,'01-09-2010'),
        '04-09-2010',0,130,null,1, 0)
) AS tempTable  --now you can join here with other tables
0 голосов
/ 06 июня 2017

Другое отличие - второй способ (with tableName as ...), приводящий к временной таблице ReadOnly.Но первым способом (declare table) вы можете изменить данные таблицы.

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