powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Непонятки с производительностью STRING_SPLIT
25 сообщений из 32, страница 1 из 2
Непонятки с производительностью STRING_SPLIT
    #39687045
Lepsik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Думал встроенная STRING_SPLIT будет явно быстрее моего велосипеда (не помню откуда стыреного и мной допиленного).

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
create FUNCTION [dbo].[fn_splitter]( @String NVARCHAR(4000), @ch char )
RETURNS TABLE 
WITH SCHEMABINDING
AS
RETURN 
(
    WITH Split( stpos, endpos ) 
    AS(
        SELECT 0          AS stpos, CHARINDEX(@ch, @String)              AS endpos
        UNION ALL
        SELECT endpos + 1 AS stpos, CHARINDEX(@ch, @String, endpos + 1 ) AS endpos 
          FROM Split
          WHERE endpos > 0
    )
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS Id,
           LTRIM(RTRIM(SUBSTRING( @String, stpos, COALESCE(NULLIF(endpos, 0), LEN(@String) + 1) - stpos))) AS Item
      FROM Split
)
GO



В таблице 176 тыс значений с пробелами, вставка 410тыс значений.

Код: sql
1.
2.
3.
select l.lake_name, f.Item into testa0 from lake l
cross apply dbo.fn_splitter1( l.lake_name, ' ' ) f
where CHARINDEX(' ', l.lake_name ) > 0 



С моей функцией вставка 1 сек, со встроеной фунцией 7 сек.

Код: sql
1.
2.
3.
select l.lake_name, f.value into testb0 from lake l
cross apply STRING_SPLIT( l.lake_name, ' ' ) f
where CHARINDEX(' ', l.lake_name ) > 0 



Где засада?
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687056
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lepsik,

CHARINDEX? STRING_SPLIT не требует проверки.
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687153
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lepsik,

STRING_SPLIT в текущей реализации тот еще тормоз, но ваш "велосипед" еще тормознее.
Так что вы, видимо, что-то где-то напутали.
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687171
Lepsik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовLepsik,

CHARINDEX? STRING_SPLIT не требует проверки.

каким образом where на что-то повлияет? Без него тот же результат. 1:7
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687172
Lepsik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmLepsik,

STRING_SPLIT в текущей реализации тот еще тормоз, но ваш "велосипед" еще тормознее.
Так что вы, видимо, что-то где-то напутали.

Есть что по существу сказать? Репо я выложил.
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687179
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LepsikinvmLepsik,

STRING_SPLIT в текущей реализации тот еще тормоз, но ваш "велосипед" еще тормознее.
Так что вы, видимо, что-то где-то напутали.

Есть что по существу сказать? Репо я выложил.Я запустил, на маленькой таблице (1000) функция медленнее в 5 раз
На большой (1000000) сплит медленее в 10 раз (6 и 60 секунд)
На маленькой таблице, но с большими строками (1000 по 8000 символов), сплит выполняется 180 секунд, а функция падает The maximum recursion 100 has been exhausted before statement completion.
Ну и вообще (если поправить maxrecursion) в ней ошибки: Invalid length parameter passed to the LEFT or SUBSTRING function.
LepsikГде засада?Хм, никакой засады, сплит медленнее вашей функции при определённых условиях.
Зато она работает без ошибок.
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687285
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LepsikЕсть что по существу сказать? Репо я выложил.Именно, что "репо".
Репро - это то, что можно взять, запустить и увидеть (или не увидеть) проблему. Так что вашему репо до репро еще очень далеко.

На форуме есть темы с обсуждением и примерами различных вариантов функций разбиения строки. Найдите себе среди них подходящий.
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687362
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
STRING_SPLIT предназначен по своему духу для преобразования входного параметра в табличную форму. "Можно" не равно "нужно". Хранение в таблице неатомарных данных - ересь чистой воды. ;)
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687401
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовSTRING_SPLIT предназначен по своему духу для преобразования входного параметра в табличную форму. "Можно" не равно "нужно". Хранение в таблице неатомарных данных - ересь чистой воды. ;)Да, поэтому было принято решение сделать его медленным :-)

По моему, просто это делали криворукие программисты, да ещё наверняка обходными путями (типа, вкорячили через .NET)
Это же надо, сделать его сравнимым или даже более медленным, чем парс рекурсивными запросами по строкам на T-SQL
Возмутительно.
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687414
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если бы просили меня, то я бы ответил, что использую для тех же целей SplitString_Multi от Adam Machanic. А то действительно нет доверия индусам :)
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687418
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосов,

Если бы просили меня, то я бы ответил, что если вам постоянно надо пользоваться сплитами, то у вас кака-то проблема в архитектуре.
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687421
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmLepsikЕсть что по существу сказать? Репо я выложил.Именно, что "репо".
Репро - это то, что можно взять, запустить и увидеть (или не увидеть) проблему. Так что вашему репо до репро еще очень далеко.

На форуме есть темы с обсуждением и примерами различных вариантов функций разбиения строки. Найдите себе среди них подходящий.Например:

Функция, которая делит строку на слова
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687422
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaK,

Я о том же. Надо хранить атомарные данные в таблицах. Разбивать требуется списки перечислений для процедур репортинг сервиса.
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687453
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexeyvgПо моему, просто это делали криворукие программистыДа. Только в другом месте :)

1. Функция split_string действительно тормозная;
2. Тем не менее, split_string гораздо быстрее функции ТС'а;
3. Есть аномальное поведение split_string в параллельных планах.

Репро
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
use tempdb;
go

if object_id('dbo.fn_splitter', 'IF') is not null
 drop function dbo.fn_splitter;
go

create FUNCTION [dbo].[fn_splitter]( @String NVARCHAR(4000), @ch char )
RETURNS TABLE 
WITH SCHEMABINDING
AS
RETURN 
(
    WITH Split( stpos, endpos ) 
    AS(
        SELECT 0          AS stpos, CHARINDEX(@ch, @String)              AS endpos
        UNION ALL
        SELECT endpos + 1 AS stpos, CHARINDEX(@ch, @String, endpos + 1 ) AS endpos 
          FROM Split
          WHERE endpos > 0
    )
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS Id,
           LTRIM(RTRIM(SUBSTRING( @String, stpos, COALESCE(NULLIF(endpos, 0), LEN(@String) + 1) - stpos))) AS Item
      FROM Split
)
GO

/************************/
/* Settings of the Test */
/************************/
declare
 @s nvarchar(max),
 @pl int = 30,
 @pc int = 5,
 @rc int = 100000;
/************************/

select
 @s = stuff((
  select top (@pc) ',' + right(replicate('0', @pl) + cast(row_number() over (order by (select 1)) as nvarchar(30)), @pl) from (select a.number from master.dbo.spt_values a cross join master.dbo.spt_values b) t for xml path(''), type
 ).value('.', 'nvarchar(max)'), 1, 1, '');

if object_id('tempdb..#t', 'U') is not null
 drop table #t;

select top(@rc)
 row_number() over (order by (select 1)) as n, @s as s
into
 #t
from
 master.dbo.spt_values a cross join
 master.dbo.spt_values b;
go

if object_id('dbo.t1', 'U') is not null
 drop table dbo.t1;

if object_id('dbo.t2', 'U') is not null
 drop table dbo.t2;

if object_id('dbo.t3', 'U') is not null
 drop table dbo.t3;

if object_id('dbo.t4', 'U') is not null
 drop table dbo.t4;
go

set statistics xml, time on;
go

select t.n, a.Item into dbo.t1 from #t t cross apply dbo.fn_splitter(t.s, ',') a option (querytraceon 8649);
select t.n, a.Item into dbo.t2 from #t t cross apply dbo.fn_splitter(t.s, ',') a option (maxdop 1);

select t.n, a.Value into dbo.t3 from #t t cross apply string_split(t.s, ',') a option (querytraceon 8649);
select t.n, a.Value into dbo.t4 from #t t cross apply string_split(t.s, ',') a option (maxdop 1);
go

set statistics xml, time off;
go

drop function dbo.fn_splitter;
drop table dbo.t1, dbo.t2, dbo.t3, dbo.t4;
go

...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687558
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

автор3. Есть аномальное поведение split_string в параллельных планах.

на что смотреть?
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687568
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKна что смотреть?На CPU при сериальном и параллельном планах.
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687596
Lepsik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKВладислав Колосов,

Если бы просили меня, то я бы ответил, что если вам постоянно надо пользоваться сплитами, то у вас кака-то проблема в архитектуре.

Представьте что ваша работа - писать репорты, где в качестве аргументов могут использоватся списки.

Архитектура плохая?
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687598
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LepsikTaPaKВладислав Колосов,

Если бы просили меня, то я бы ответил, что если вам постоянно надо пользоваться сплитами, то у вас кака-то проблема в архитектуре.

Представьте что ваша работа - писать репорты, где в качестве аргументов могут использоватся списки.

Архитектура плохая?
вы точтно понимаете, что означает архитектура?
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687600
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmTaPaKна что смотреть?На CPU при сериальном и параллельном планах.
Ну как по мне здесь не из-за STRING_SPLIT, а из за вставки.
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687640
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaKНу как по мне здесь не из-за STRING_SPLIT, а из за вставки.Поясните, что именно вызвало рост CPU time в параллельном плане с string_split, в сравнении с сериальным и не вызвало в аналогичном с fn_splitter.
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687645
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmTaPaKНу как по мне здесь не из-за STRING_SPLIT, а из за вставки.Поясните, что именно вызвало рост CPU time в параллельном плане с string_split, в сравнении с сериальным и не вызвало в аналогичном с fn_splitter.
Ну я смотрел только на string_split.
Сам оператор в параллельном плане даёт 4572/299 против 2145/2145 в последовательном. Это на MAXDOP 16. Говорить про аномальное поведение как минимум странно.
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687660
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

ну и

Код: sql
1.
2.
INSERT INTO	dbo.t1  select t.n, a.Item from #t t cross apply dbo.fn_splitter(t.s, ',') a option (querytraceon 8649, MAXDOP 16);
INSERT INTO	dbo.t2  select t.n, a.Value from #t t cross apply string_split(t.s, ',') a option (use hint('ENABLE_PARALLEL_PLAN_PREFERENCE'),MAXDOP 16);


даёт абсолютно обратную картину, имхо вопрос именно к SELECT INTO которая как по мне проклята :)
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687677
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TaPaK,

У меня для string_split парллельный/сериальный CPU time - 7689/3078
А должно быть сопоставимо. Что и видно для fn_splitter - 6155/5750
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687678
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmTaPaK,

У меня для string_split парллельный/сериальный CPU time - 7689/3078
А должно быть сопоставимо. Что и видно для fn_splitter - 6155/5750
вы про выполнение целиком?
...
Рейтинг: 0 / 0
Непонятки с производительностью STRING_SPLIT
    #39687701
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm1. Функция split_string действительно тормозная;
2. Тем не менее, split_string гораздо быстрее функции ТС'а;
3. Есть аномальное поведение split_string в параллельных планах.Так вот у ТС и получается своя функция быстрее split_string, именно из за тормознутости последней в параллельных планах. Это и по вашему репро видно.
В 9 раз тормознутее, если split_string выполняется параллельно, и в 5 раз - если она выполняется в одном потоке, а функция ТС'а во многих (там, понятно, сама split_string быстрее, но функция ТС'а берёт параллельным выполнением)
ТС'а
Для миллиона строк:
function queryoptionCPU duration reads fn_splitter querytraceon 864963406 17820 46081026fn_splitter maxdop 1 198781 208033 46077786string_split querytraceon 8649263141 140406 6515962string_split maxdop 1 79266 87837 6515919
...
Рейтинг: 0 / 0
25 сообщений из 32, страница 1 из 2
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Непонятки с производительностью STRING_SPLIT
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]