Почему SQL Функция базы данных сервера работает медленно | Многозначный параметр SSRS с хранимой процедурой - PullRequest
0 голосов
/ 23 апреля 2020

Я ищу понимание некоторых интригующих проблем при работе с SQL Сервером.

Фон

  • У нас работает несколько отчетов SSRS APS (SQL Server PDW / MPP)
  • Наборы данных отчетов со встроенными запросами выполняются непосредственно в базе данных. Теперь одна из самых больших таблиц была сделана для разделения на таблицы «текущие» и «истории» (таблица «Текущие» содержит данные последних лет), очевидно, для повышения производительности этих отчетов.
  • Мне нужно изменить отчеты SSRS таким образом, чтобы те же отчеты теперь перенаправлялись в любую из этих таблиц в зависимости от того, какой "год" был выбран в качестве одного из параметров.
  • My подход к проектированию: я решил использовать хранимую процедуру базы данных (SP) в наборах данных отчетов SSRS, создавая необходимые логики c в хранимой процедуре.

Постановка задачи

  • Между прочим, многозначные параметры не будут работать так, как я предполагал.

  • Когда я посмотрел на это, мне показалось, что это известный выпуск и одна из плохо поддерживаемых функций SSRS. Кажется, что множественные значения в многозначном параметре рассматриваются только как одно значение, хотя при печати они выглядят как множественные значения, как в

    val1, val2, val3

  • Вот несколько постов, на которые я ссылался: Link1 Link2

  • Затем я решил найти обходной путь, чтобы это заработало, после некоторых предложения в постах выше и ниже.

Link3

  • После многих попыток мне удалось получить это работая над созданием логики c, как показано ниже

    • Шаг 1: Из SSRS параметр изменяется как:

      =Join(Parameters!param_1.Value,"|")
      
    • Step2: Использовал фрагмент кода в SP для преобразования / форматирования многозначного параметра и сохранения его в новой переменной (SQLString)

      --Relevant code:
      
      -- Block of conversion code
      -- to convert/format the multivalued param and store it in a new variable
      -- after this the SQLSTRING variable's final value is set as 
      -- |val1|val2|val3|
      
      -- Relevant where clause
      AND 
          (@SQLString LIKE '%|' + tbl.attr_1 + '|%')  
      
  • Это сработало! Хотя, оговорки упоминали, что это, безусловно, не производительный. Результаты в отчете SSRS были быстрыми (хотя это был всего лишь пример запроса).

  • Теперь я решил преобразовать «Блок кода преобразования» в скалярную функцию, ссылаясь ниже, чтобы Я могу вызывать эту функцию каждый раз для каждого многозначного параметра. Ссылка 4

  • Это также сработало, но оно было СЛИШКОМ медленным (для того же примера запроса только с одним многозначным параметром, т.е. одним вызовом этой функции).

Вопрос (ы)

  • Меня озадачивает (я не очень хорошо разбираюсь в SQL внутренностях сервера) относительно ПОЧЕМУ преобразование фрагмента кода в функцию замедлит выполнение запроса до такой степени.

Буду признателен за любые указатели.

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 24 апреля 2020

Я думаю, что нашел ответ на свой вопрос, как объяснено на следующей странице. Скалер UDF

0 голосов
/ 23 апреля 2020

Я всегда манипулирую объединенными параметрами в таблице в хранимой процедуре, а затем внутренним соединением с этой таблицей.

Пример с использованием моих собственных данных:

Используемое мной соединение SSRS:

=Join(Parameters!param_1.Value,"#~--~#")

Затем хранимая процедура:

create proc whatever
@profs varchar(8000)
as

declare @profs_t table (ProfName varchar(70))
declare @delim varchar(10) = '#~--~#'
declare @delimlen int = len(@delim)
declare @idx int = 1 - @delimlen

while charindex(@delim, @profs, @idx + @delimlen) <> 0
    begin
        insert into @profs_t
        select substring(@profs, @idx + @delimlen, charindex(@delim, @profs, @idx + @delimlen) - @idx - @delimlen)
        set @idx = charindex(@delim, @profs, @idx + @delimlen)
    end
insert into @profs_t
select substring(@profs, @idx + @delimlen , len(@profs))

select *
from @profs_t pt
inner join professionals p on p.profname = pt.profname

Преобразует объединенные параметры из SSRS в табличную переменную (вы также можете легко использовать временную таблицу). Это довольно обобщенно c и может использовать любые разделители, даже несколько разделителей символов (как показано). Я полагаю, что разделитель может быть передан в pro c в качестве параметра тоже.

...