Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Непонятки с производительностью STRING_SPLIT / 25 сообщений из 32, страница 1 из 2
13.08.2018, 18:21
    #39687045
Lepsik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с производительностью STRING_SPLIT
Думал встроенная 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
13.08.2018, 18:37
    #39687056
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с производительностью STRING_SPLIT
Lepsik,

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

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

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

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

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

Есть что по существу сказать? Репо я выложил.
...
Рейтинг: 0 / 0
14.08.2018, 00:18
    #39687179
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с производительностью STRING_SPLIT
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
14.08.2018, 10:06
    #39687285
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с производительностью STRING_SPLIT
LepsikЕсть что по существу сказать? Репо я выложил.Именно, что "репо".
Репро - это то, что можно взять, запустить и увидеть (или не увидеть) проблему. Так что вашему репо до репро еще очень далеко.

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

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

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

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

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

Я о том же. Надо хранить атомарные данные в таблицах. Разбивать требуется списки перечислений для процедур репортинг сервиса.
...
Рейтинг: 0 / 0
14.08.2018, 13:41
    #39687453
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с производительностью STRING_SPLIT
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
14.08.2018, 15:38
    #39687558
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с производительностью STRING_SPLIT
invm,

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

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

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

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

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

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

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

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

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

У меня для string_split парллельный/сериальный CPU time - 7689/3078
А должно быть сопоставимо. Что и видно для fn_splitter - 6155/5750
вы про выполнение целиком?
...
Рейтинг: 0 / 0
14.08.2018, 18:24
    #39687701
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Непонятки с производительностью STRING_SPLIT
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
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Непонятки с производительностью STRING_SPLIT / 25 сообщений из 32, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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