STRING_split Performance Issue - PullRequest
       18

STRING_split Performance Issue

0 голосов
/ 04 июля 2018

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

Для первого запроса я использовал пользовательскую функцию:

Функция, определенная пользователем для разлитой жидкости.

Create FUNCTION [dbo].[Split_S]
(
    @sInputList VARCHAR(MAX)
   ,@sDelimiter VARCHAR(8)      
) 
RETURNS @List TABLE ([item] VARCHAR(8000)) 
AS
BEGIN
DECLARE @sItem VARCHAR(MAX) 
WHILE CHARINDEX(@sDelimiter,@sInputList,0) <> 0
BEGIN
    SELECT
        @sItem=RTRIM(LTRIM(SUBSTRING(@sInputList,1,CHARINDEX(@sDelimiter,@sInputList,0)-1)))
        ,@sInputList=RTRIM(LTRIM(SUBSTRING(@sInputList,CHARINDEX(@sDelimiter,@sInputList,0)+LEN(@sDelimiter),LEN(@sInputList))))

    IF LEN(@sItem) > 0
        INSERT INTO @List SELECT @sItem
    END

    IF LEN(@sInputList) > 0
        INSERT INTO @List SELECT @sInputList-- Put the last item in
RETURN 
END

Запрос 1:

 DECLARE @F TABLE(F BIGINT) 
INSERT INTO @F
SELECT [item] FROM [dbo].[Split_S] 
(N'82,13,51,68,6',',')

Запрос 2:

DECLARE @F2 TABLE(F BIGINT) 
INSERT INTO @F2
SELECT Value 
from  
STRING_SPLIT(N'82,13,51,68,6',',')

План запроса обоих запросов

Query Plan of Both Query

Почему 37% и с использованием STRING_SPLIT Его 63%. но если я сравниваю только оператор select, тогда стоимость запроса STRING_SPLIT составляет 1%.

Какой запрос имеет лучшую производительность и почему?

1 Ответ

0 голосов
/ 05 июля 2018

Если вы проверите только часть запроса, которая включает запрос на выборку, то вы получите, что использование STRING_SPLIT дает гораздо лучшую производительность в соответствии с планом выполнения (EP). результат будет 99% против 1%.

Но когда мы используем данные, возвращенные функцией STRING_SPLIT (например, «выберите ... в» или как в вашем случае «вставьте ... выберите»), вы можете заметить, что сервер использует « table spool (Eager Spool)", которые имеют значение. Этот оператор берет строки и сохраняет их в скрытом временном объекте, хранящемся в базе данных tempdb (идея использования этой логики заключается в том, что буферные данные могут быть повторно использованы позже в плане выполнения.) «Стремительная» катушка получает ALL строк от предыдущего оператора за один раз, что означает, что это « блокирующий оператор ».

...