Как хранимая процедура, вызывающая TVF, может быть медленнее, чем процедура, которая вставляет TVF? - PullRequest
0 голосов
/ 31 августа 2011

Вопрос:

У меня есть два представления:

V_Room, 14969 rows, 9 tables joined together
V_parkings, 3265 rows, 9 tables joined together

Тогда у меня есть представление

V_Rooms_UsageTypes with 18234 rows

, которое представляет собой объединение между V_Room и V_parkings

Затем у меня есть табличная функция, подобная этой. Функция

CREATE FUNCTION [dbo].[tfu_RPT_UsageTypesBySIADetail]
(@in_reporting_date datetime)
-- Add the parameters for the function here
RETURNS TABLE

, которая объединяет 9 таблиц и выполняет 77 подвыборов, как показано ниже, для представления V_Rooms_UsageTypes

(
        SELECT 
            ISNULL(SUM(ZO_RMArea_Area), 0.0) 
        FROM dbo.V_Rooms_UsageTypes 
        WHERE V_Rooms_UsageTypes.FL_UID = T_Floor.FL_UID 

        AND (V_Rooms_UsageTypes.DIN277_Major = 9) 
        AND (V_Rooms_UsageTypes.DIN277_Minor = 4) 

        AND (V_Rooms_UsageTypes.ZO_RMUT_DateFrom <= @in_reporting_date) 
        AND (V_Rooms_UsageTypes.ZO_RMUT_DatumTo >= @in_reporting_date) 

        AND (V_Rooms_UsageTypes.ZO_RMArea_DateFrom <= @in_reporting_date) 
        AND (V_Rooms_UsageTypes.ZO_RMArea_DatumTo >= @in_reporting_date) 

        AND (V_Rooms_UsageTypes.RM_DateFrom <= @in_reporting_date) 
        AND (V_Rooms_UsageTypes.RM_DatumTo >= @in_reporting_date) 

        AND (V_Rooms_UsageTypes.SO_DateFrom <= @in_reporting_date) 
        AND (V_Rooms_UsageTypes.SO_DatumTo >= @in_reporting_date) 

        AND (V_Rooms_UsageTypes.BG_DateFrom <= @in_reporting_date) 
        AND (V_Rooms_UsageTypes.BG_DatumTo >= @in_reporting_date) 

        AND (V_Rooms_UsageTypes.FL_DateFrom <= @in_reporting_date) 
        AND (V_Rooms_UsageTypes.FL_DatumTo >= @in_reporting_date) 
    ) AS RPT_VF_9_4 

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

вот так:

CREATE PROCEDURE [dbo].[sp_RPT_DATA_AreaByDIN277_old]
    @in_customer varchar(3),
    @in_language varchar(2),
    @in_site varchar(36),
    @in_building varchar(36),
    @in_floor varchar(36),
    @in_reporting_date varchar(50)
AS
    DECLARE
    @sql varchar(8000),
    @reporting_date datetime

    -- Abrunden des Eingabedatums auf 00:00:00 Uhr
    SET @reporting_date= CONVERT( DATETIME, @in_reporting_date ) 
    SET @reporting_date= Cast(Floor(Cast(@reporting_date As Float)) As DateTime)
    SET @in_reporting_date= CONVERT(varchar(50), @reporting_date ) 

    SET NOCOUNT ON;



    SET @sql='SELECT  

     FIELD_1_' + @in_language +' AS RPT_FIELD_1
    ,FIELD_2_' + @in_language +' AS RPT_FIELD_2
    ,FIELD_3 AS RPT_FIELD_3 
    ,table_valued_function_column1 AS RPT_table_valued_function_column1
    ,table_valued_function_column2 AS RPT_table_valued_function_column2
    ,table_valued_function_columnN AS RPT_table_valued_function_columnN 

    '



    SET @sql=@sql + 'FROM dbo.tfu_RPT_FM_NutzungsartenNachSIADetail(''' + @in_reporting_date + ''') '

    SET @sql=@sql + 'WHERE ST_Customer = ''' + @in_customer + ''' '


    IF @in_site     <> '00000000-0000-0000-0000-000000000000' SET @sql=@sql + 'AND (ST_UID = ''' + @in_site + ''') '
    IF @in_building <> '00000000-0000-0000-0000-000000000000' SET @sql=@sql + 'AND (BG_UID = ''' + @in_building + ''') '
    IF @in_floor    <> '00000000-0000-0000-0000-000000000000' SET @sql=@sql + 'AND (FL_UID = ''' + @in_floor + ''') '   

    EXECUTE (@sql) 

Теперь, как и ожидалось,это заняло довольно много времени (20 секунд) для запроса, чтобы вернуть результаты.Поэтому я переместил всю табличную функцию в динамическую хранимую процедуру sql и исключил ее скорость выполнения примерно в половину (10 с).

Вместо этого я получил время выполнения 30 с.Почему это?

1 Ответ

2 голосов
/ 31 августа 2011

Вполне возможно, что движок лучше справится с оптимизацией TVF отдельно, чем когда это просто часть гораздо большего запроса.Также динамический SQL может изменить способ кэширования планов.Вы забыли упомянуть, какую версию SQL Server вы используете, но поиграли ли вы с настройкой « optimize для специальных рабочих нагрузок » или OPTIMIZE FOR UNKNOWN ??

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