Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Медленная конкатенация varchar(MAX)  [new]
vlad4000
Member

Откуда:
Сообщений: 2
Добрый день.
Мне нужно из значений столбца с типом geometry сгенерировать строку svg. В моей функции много конкатенаций, которые работают очень медленно с varchar(Max). Функция возвращает переменную длиной ~500000

Как можно оптимизировать генерацию строки?
Выполняется 9 секунд
DECLARE @res varchar(Max) = ''
DECLARE @i int = 1
WHILE @i < 100000
BEGIN
	SET @res = @res + STR(@i)
	SET @i = @i + 1 
	IF (@i % 40000 = 0)
		SET @res = '';
END

Выполняется 12 секунд
DECLARE @res varchar(Max) = ''
DECLARE @i int = 1
WHILE @i < 100000
BEGIN
	SET @res = @res + STR(@i)
	SET @i = @i + 1 
	IF (@i % 50000 = 0)
		SET @res = '';
END

Выполняется 55 секунд
DECLARE @res varchar(Max) = ''
DECLARE @i int = 1
WHILE @i < 100000
BEGIN
	SET @res = @res + STR(@i)
	SET @i = @i + 1 
	IF (@i % 60000 = 0)
		SET @res = '';
END
5 авг 14, 19:13    [16403035]     Ответить | Цитировать Сообщить модератору
 Re: Медленная конкатенация varchar(MAX)  [new]
Crimean
Member

Откуда:
Сообщений: 13147
"перекешируйте" через varchar(8000) переменную. как-то так, грубо:

DECLARE @res varchar(Max) = ''
DECLARE @i int = 1

declare @t varchar(8000)
set @t = ''

WHILE @i < 100000
BEGIN
--	SET @res = @res + STR(@i)
	if	len( @t ) > 7000	begin
		set	@res	= @res + @t;
		set	@t		= '';
	end	else	begin
		set	@t		= @t + STR(@i);
	end

	SET @i = @i + 1 

	IF (@i % 50000 = 0)	begin
		SET @res	= '';
		set	@t		= '';
	end
END
5 авг 14, 19:21    [16403042]     Ответить | Цитировать Сообщить модератору
 Re: Медленная конкатенация varchar(MAX)  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
Или складывайте промежуточные результаты в табличную переменную, а в конце конкатенируйте все чохом:
declare @dt datetime2 = sysdatetime();
declare @t table (i int identity primary key, s varchar(max));

DECLARE @res varchar(Max) = ''
DECLARE @i int = 1
WHILE @i < 60000
BEGIN
	insert into @t (s) values (str(@i))
	SET @i = @i + 1 
END

select @res = (select s as [*] from @t order by i for xml path(''), type).value('.', 'varchar(max)');
select datalength(@res), datediff(ms, @dt, sysdatetime());
go
5 авг 14, 19:37    [16403074]     Ответить | Цитировать Сообщить модератору
 Re: Медленная конкатенация varchar(MAX)  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4900
Вообще складывать строки лучше не на уровне БД, на на c# с помощью StringBuilder. Это не задача БД
6 авг 14, 12:01    [16405669]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить