Как вернуть несколько значений из функции с табличным значением для ускорения выполнения запроса - PullRequest
1 голос
/ 05 августа 2020

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

Таблица customerAddress немного шаткая, в ней есть записи для каждой строки адреса. Таким образом, customer_id может содержать от 2 до 4 записей. My WHERE ищет последние 4 числа c, и в нем есть, а в первой строке никогда не должно быть города, штата, почтового индекса.

Вот как выглядит таблица customerAddress:

customer_id address_line_id address_data
10447           3           CULVER CITY, CA  90233-6011
10893           3           VIRGINIA BEACH, VA  23452
10461           3           DOWNERS GROVE,  IL  60515
10894           1           1111 BOHM DRIVE
10894           2           PO BOX 109
10894           3           LITTLE CHUTE, WI  54140-0109
10895           1           1990 WEST 32ND AVE.
10895           2           DENVER, CO 80211

Итак, вот мой запрос:

SELECT customer_id, address_line_id, address_data, oa.*
  INTO #tmpAddress
  FROM customerAddress
  OUTER APPLY
 ( SELECT * FROM [dbo].[parseCityStateZip](customerAddress.address_data)    ) oa
  WHERE
    address_data LIKE '%,%' AND 
    ISNUMERIC( RIGHT(address_data,4) ) = 1 AND
    address_line_id != 1
ORDER BY customer_id, address_line_id

Вот план выполнения запроса. Если я читаю правильно (что, вероятно, не так), функция с табличным значением выполнялась за 9 минут 33 секунды, но фильтр был 123% ?? https://www.brentozar.com/pastetheplan/?id=S13IITvZw

Я использовал OUTER APPLY, потому что думал, что это лучше, чем вызывать функцию для каждого поля, и нет ничего, что я мог бы присоединить к нему для LEFT JOIN.

Вот моя табличная функция, которую я вызываю в OUTER APPLY

ALTER FUNCTION [dbo].[parseCityStateZip] (@inStr varchar(255) )
    RETURNS @returnTable
      TABLE (
        [city] varchar(255),
        [state]  varchar(255),
        [zip] varchar(12),
        [country] varchar(50) NULL,
        [intlFlag] bit NOT NULL DEFAULT(0))
AS
BEGIN

    DECLARE
        @newStr varchar(255), @strCity varchar(255), @strState varchar(255), @strZip varchar(12), @strCountry varchar(255),
        @strIntlFlag bit

    -- Determines if Zip Code is 5 or 9 Digits
    --  Stores to variable and chops it off saving the remainign to @newStr
    IF CHARINDEX('-', @inStr, 0) > 0
      BEGIN
        SELECT @strZip = RIGHT(@inStr, 10)
        SELECT @newStr = TRIM(SUBSTRING(@inStr, 0, LEN(@inStr) - 9))
      END
    ELSE
      BEGIN
        SELECT @strZip = RIGHT(@inStr, 5)
        SELECT @newStr = TRIM(SUBSTRING(@inStr, 0, LEN(@inStr) - 4))
      END

    -- Looks for the , separating City, State
    --  Saves everything before the , and City, and after as State
    --  Use TRIM to remove extra spaces before or after the State
    SELECT @strCity =  TRIM( SUBSTRING( @newStr, 0, CHARINDEX(',', @newStr, 0) ) )
    SELECT @strState = ULTRA.dbo.RemoveNonAlphaCharacters( TRIM( SUBSTRING( @newStr, CHARINDEX(',', @newStr, 0) + 1, LEN(@newStr) - CHARINDEX(',', @newStr, 0) ) ) )
    
    -- Checks to see if the State matches a state in the info table, and is in the United States
    IF EXISTS( SELECT * FROM [ULTRA].[dbo].[CityStateInfo] WHERE [Country] = 'United States' AND ([State_long] = @strState OR [State_abbr] = @strState))
        SELECT @strCountry = 'United States', @strIntlFlag = 0
    ELSE
        SELECT @strCountry = 'INTERNATIONAL', @strIntlFlag = 1

    INSERT INTO @returnTable VALUES (@strCity, @strState, @strZip, @strCountry, @strIntlFlag)
    RETURN  
END

И вот план выполнения для хорошей меры: https://www.brentozar.com/pastetheplan/?id=BkFCQawZP

Есть ли способ вывести все поля в запросе, например:

SELECT
    customer_id,
    address_data,
    (SELECT * FROM [parseCityStateZip](address_data))
  FROM customerAddress

Ускорит ли это запрос? Если нет, что можно сделать, чтобы ускорить его?

Я использую последний SQL сервер и SSMS

...