В хранимой процедуре я использую таблицу 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
вызывает значительную нагрузку на эту процедуру. Что я могу сделать, чтобы улучшить производительность и сохранить объекты такими, как есть?