SQL Server объединяет или заменяет, какой из них лучше (быстрее) - PullRequest
0 голосов
/ 19 сентября 2019

Мне приходится каждый раз генерировать очень длинную процедуру для системы отчетности, поэтому я создал шаблон для своей процедуры и для этого требуется замена частей, но я мог бы сделать это с помощью Concat или + (&)

например:

    set @query = '... and (      
         --@InnerQueries 
    )'

    set @query = replace(@query,'--@InnerQueries',@otherValues)

против

set @query += ' and exists (...)'
if(@xxx is not null)
    set @query += 'and not exists (...)'

с подходом замены, это более читабельно и легко для меня, но ради оптимизации, как насчет Concat и присоединения строки вместе?
с заменой: есть много поиска, но меньше создания строк и с concat: много создания строки, но нет поиска, так что идея?

Ответы [ 2 ]

0 голосов
/ 20 сентября 2019

обновление 2: здесь может быть что-то не хватает: если я изменю первую переменную: @sourceText_Replace на максимальное значение 8000 символов и продолжу добавлять к нему:

set @sourceText_Replace += '8000 character length'
set @sourceText_Replace +=@sourceText_Replace
set @sourceText_Replace +=@sourceText_Replace
set @sourceText_Replace +=@sourceText_Replace
set @sourceText_Replace +=@sourceText_Replace
set @sourceText_Replace +=@sourceText_Replace
set @sourceText_Replace +=@sourceText_Replace

работает нормально, даже если идти до: 16384017 символов длиной

, поэтому любая идея здесь так же хороша, как моя

оригинальный ответ:

Подводя итог (и если я не сделал никаких ошибок):

если вы ищете в длинном тексте, даже не думайте об использовании замены, это заняло секунды, а не миллисекунды, но для concat, очевидно, не имеет никакого значения

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

для длинного текста, я не удосужился запустить цикл более 20 раз, потому что это заняло несколько минут.

smallText: set @destSmallText_Replace =

longText: установить @destSmallText_Replace + =

comparisionSheet

вот код для теста:

SET NOCOUNT ON

drop table if exists #tempReplace
drop table if exists #tempConcat

create table #tempReplace
(
    [txt] nvarchar(max) not null
)
create table #tempConcat
(
    [txt] nvarchar(max) not null
)



declare  @sourceText_Replace  nvarchar(max) = 'small1 text to replace @textToBeReplaced after param text'
declare  @text_Replace   nvarchar(max) = @sourceText_Replace

declare  @textToSearch  nvarchar(max) = '@textToBeReplaced'
declare  @textToReplace  nvarchar(max) = 'textToBeReplaced'

declare  @concat_Start  nvarchar(max) = 'small1 text to replace'
declare  @concat_End  nvarchar(max) = 'after param text'
declare  @text_Concat   nvarchar(max) = @concat_Start


declare @whileCounter int =0
declare @maxCounter int = 5

declare @startTime datetime = getdate();
declare @endTime datetime = getdate();

begin
    set @startTime = getDate();

    while(@whileCounter <=@maxCounter)
    begin
    --long text
    set @text_Replace += replace(@sourceText_Replace,@textToSearch,@textToReplace + convert(nvarchar(10), @whileCounter)) + @textToSearch
    --small text
    --set @text_Replace = replace(@sourceText_Replace,@textToSearch,@textToReplace + convert(nvarchar(10), @whileCounter)) + @textToSearch

    --print @destSmallText_Replace 

    insert into #tempReplace values(@text_Replace)
    set @whileCounter+=1
    end
    set @endTime = getDate();
    print 'passedTime ' + Convert(nvarchar(20),  DATEPART(millisecond, @endTime) - DATEPART(millisecond, @startTime))

end

begin
    set @whileCounter = 0;


    set @startTime = getDate();
    while(@whileCounter <=@maxCounter)
    begin
    set @text_Concat += concat(@concat_Start,@textToReplace + convert(nvarchar(10), @whileCounter),@concat_End) + @textToSearch
    --print @sourceSmallText_Concat 

    insert into #tempConcat values(@text_Concat)
    set @whileCounter+=1
    end

    set @endTime = getDate();
    print 'passedTime ' + Convert(nvarchar(20),    DATEPART(millisecond, @endTime) - DATEPART(millisecond, @startTime))
end
0 голосов
/ 19 сентября 2019

Я предполагаю, что вы говорите об использовании CONCAT или REPLACE для создания SQL, а затем запускаете его.Если в конечном итоге вы обработаете менее 100 ЗАМЕНА, я бы выбрал этот подход, а не CONCAT, потому что он более читабелен.

Если, однако, вы говорите об использовании concat / replace для создания выходных данных отчета инапример, вы будете выполнять 100 операций REPLACE на строку на миллион строк, я бы сделал маршрут CONCAT

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...