Как добавить CTE для улучшения производительности хранимых процедур? - PullRequest
0 голосов
/ 03 мая 2019

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

CREATE PROCEDURE [Schema].[ProcName]
    (@PhoneNum  VARCHAR(100)
     @EmailAddr VARCHAR(100)
     @DriverLic VARCHAR(100)
     @EligiblityDate VARCHAR(10))
AS
BEGIN
SET NOCOUNT ON;
    DECLARE @Phone BIT = 0,
            @Email BIT = 0,
            @License BIT = 0

    IF (SELECT Value FROM Table 
        WHERE Product = 'ProductA' 
          AND @EligibilityDate BETWEEN EligStart AND EligEnd 
          AND ProductType = 1 
          AND Value = @PhoneNum 
          AND IsActive = 1) 
        SET @Phone = 1

    IF (SELECT Value FROM Table 
        WHERE Product = 'ProductA' 
          AND @EligibilityDate BETWEEN EligStart AND EligEnd 
          AND ProductType = 2 
          AND Value = @EmailAddr 
          AND IsActive = 1) 
        SET @Email = 1

    IF (SELECT Value FROM Table 
        WHERE Product = 'ProductA' 
          AND @EligibilityDate BETWEEN EligStart AND EligEnd 
          AND ProductType = 3 
          AND Value = @DriverLic 
          AND IsActive = 1) 
        SET @License = 1

    SELECT 
        @Phone AS Phone,
        @Email AS Email,
        @License AS License;

    RETURN 0;

Я надеялся улучшить производительность этого запроса с помощью CTE.Тем не менее, я не уверен, как это сделать, поскольку я никогда раньше не использовал CTE.

Ответы [ 2 ]

2 голосов
/ 03 мая 2019

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

Мне кажется, что вам здесь нужно нечто похожее на следующее:

Create Procedure [Schema].[ProcName]
    (@PhoneNum   VARCHAR(100),
    @EmailAddr  VARCHAR(100),
    @DriverLic  VARCHAR(100),
    @EligiblityDate VARCHAR(10))
AS
BEGIN

    select
        max(case when ProductType = 1 and [Value] = @PhoneNum then 1 else 0 end) as PhoneNum,
        max(case when ProductType = 2 and [Value] = @EmailAddr then 1 else 0 end) as EmailAddr,
        max(case when ProductType = 3 and [Value] = @DriverLic then 1 else 0 end) as DriverLic
    from [Table]
    WHERE
        Product = 'ProductExample'
        AND @EligibilityDate BETWEEN EligStart and EligEnd
        AND IsActive = 1
END

Это похоже на объединение нескольких запросов (вы правы, когда будете подозрительныповторяйте подобный код!) в одном запросе, но нет необходимости в дополнительном выборе.

0 голосов
/ 03 мая 2019

Я думаю, вы хотите это

CREATE PROCEDURE [Schema].[ProcName]
    (@PhoneNum  VARCHAR(100),
     @EmailAddr VARCHAR(100),
     @DriverLic VARCHAR(100),
     @EligiblityDate VARCHAR(10))
AS
BEGIN
SET NOCOUNT ON;
    DECLARE @Phone BIT = 0,
            @Email BIT = 0,
            @License BIT = 0

    SELECT @Phone = case when ProductType = 1 and Value = @PhoneNum then 1 else 0 end,
        @Email = case when ProductType = 2 and Value = @EmailAddr then 1 else 0 end,
        @License = case when ProductType = 3 and Value = @DriverLic then 1 else 0 end
    FROM Table 
        WHERE Product = 'ProductA' 
          AND @EligibilityDate BETWEEN EligStart AND EligEnd 
          AND ProductType = 1 

    SELECT 
        @Phone AS Phone,
        @Email AS Email,
        @License AS License;

    RETURN 0;
END
...