Возвращение объекта json в select - вызывает замедление - PullRequest
4 голосов
/ 21 января 2020

В хранимой процедуре я использую таблицу CTE, чтобы вернуть набор данных как JSON. По мере увеличения объема данных я заметил, что одна конкретная часть хранимой процедуры вызывает замедление после выполнения плана выполнения.

Есть 4 таблицы, и они связаны с помощью ID. Для простоты я буду ссылаться на них как Table1, Table2, Table3 and Table4.

Table1 
(
    Id (int primary key), 
    Colum1,
    Colum2,
    ---
)

Table2
(
    Id (int primary Key)
    Table1Id (foreign key) --To table 1 Id,(non-unique, non-clustered) index
    Colum1,
    Colum2,
    ---
)

Table3
(
    Id (int primary key),
    Table2Id (foreign key) -- To table 2 Id, has (non-unique, non-clustered) index
    Table4id (foreign key) -- To table 4 id, has (non-unique, non-clustered) index
    Colum1,
    Colum2,
    ---
)

Table4
(
    Id (int primary key),
    Colum1,
    Colum2,
    --
)

В Table1 содержится примерно 55000 записей, а в Table2 - 75000 записей. Я передаю фильтр JSON хранимой процедуре, чтобы выполнить некоторую фильтрацию, и мой окончательный результат возвращается как объект JSON. Тем не менее, ни фильтр, ни возврат на json не вызывают замедления. В моем операторе SELECT я строю объект с использованием подзапроса. Вот что вызывает проблему.

Вот запрос:

(
 SELECT

      Colum1,
      Colum2,
      Colum3,
      ...
      --Causes Slowness
      Object1 = (
                       SELECT t2.Id,
                              t2.Table1Id,
                              t2.Colum1,
                              t2.Colum2,
                              ...
                              -- Causes Slowness
                              Object2 = (
                                  SELECT t3.Id,
                                         t3.Table2id,
                                         t3.Table3Id,
                                         t4.Colum1 + ' ' + t4.Colum2 as newcolumn,
                                         ...
                                  FROM Table3 t3
                                  INNER JOIN Table4 t4
                                      ON t3.Table4Id = t4.Id
                                  WHERE t2.Id = t3.Table2Id
                                  ORDER BY CASE WHEN @OrderByAndOrder = 'colum1 asc' THEN u.Colum1 END ASC,
                                           CASE WHEN @OrderByAndOrder = 'colum1 desc' THEN u.Colum1 END DESC
                                  FOR JSON PATH, INCLUDE_NULL_VALUES
                                  )
                              FROM Table2 t2
                              WHERE t2.Table1Id = s.Id
                                AND
                              --Search by (;) colum1
                                (
                                        (ISJSON(@Filter) IS NULL) OR
                                        (JSON_VALUE(@Filter, '$.Colum1') = N'') OR
                                        (JSON_VALUE(@Filter, '$.Colum1') IS NULL) OR
                                        ((ISJSON(@Filter) IS NOT NULL) AND
                                            (JSON_VALUE(@Filter, '$.Colum1') <> N'') AND
                                                EXISTS( SELECT * FROM STRING_SPLIT(JSON_VALUE(@Filter, '$.Filter'), ';')
                                                        WHERE t2.[Colum1] LIKE CONCAT('%', [Value], '%')
                                                        AND [value] <> ''
                                                    )
                                            )
                                    ) )
                                ORDER BY
                                CASE WHEN @OrderByAndOrder = 'Colum1 asc' then t2.[Target] END ASC,
                                CASE WHEN @OrderByAndOrder = 'Colum1 desc' then t2.[Target] END DESC,
                                FOR JSON PATH, INCLUDE_NULL_VALUES
                          )
FROM Table1 (NOLOCK) mainTable
INNER JOIN Table2 t2
 ON mainTable.Id = t2.Table1Id
WHERE
mainTable.Id IN (SELECT Id FROM #Ids) --Could potentially join
AND
...
--same JSON filters on columns in mainTable

--Doing some more stuff with cte

Заполнение Object1 и Object2 в Object1 вызывает значительную нагрузку на эту процедуру. Что я могу сделать, чтобы улучшить производительность и сохранить объекты такими, как есть?

1 Ответ

0 голосов
/ 31 января 2020

Не уверен, что это сработает, но вы должны попытаться добавить OPTION (RECOMPILE) в конце вашего запроса.

...