Есть ли способ улучшить производительность следующего запроса CTE (@E
и @R
- это таблицы с индексами в реальной системе):
DECLARE @id bigint = 1
DECLARE @E TABLE
(
id bigint,
name varchar(50)
)
DECLARE @R TABLE
(
child_id bigint,
parent_id bigint
)
INSERT INTO @E SELECT 1, 'one'
INSERT INTO @E SELECT 2, 'two'
INSERT INTO @E SELECT 3, 'three'
INSERT INTO @E SELECT 4, 'four'
INSERT INTO @E SELECT 5, 'five'
INSERT INTO @E SELECT 6, 'six'
INSERT INTO @E SELECT 7, 'seven'
INSERT INTO @R SELECT 1, 2
INSERT INTO @R SELECT 1, 3
INSERT INTO @R SELECT 3, 4
INSERT INTO @R SELECT 5, 4
INSERT INTO @R SELECT 3, 6
INSERT INTO @R SELECT 7, 4
; WITH cte
(
child_id,
parent_id
)
AS (
SELECT * FROM @R R
WHERE R.child_id = @id
UNION ALL
SELECT R.* FROM @R R
INNER JOIN cte ON CTE.parent_id = R.child_id
)
SELECT * FROM @E E
WHERE e.id = @id
UNION ALL
SELECT P.* FROM @E E
INNER JOIN cte ON 1=1
INNER JOIN @E P ON P.id = cte.parent_id
WHERE e.id = @id
ORDER BY 1
Ожидаемые результаты:
id | name
1 | one
2 | two
3 | three
4 | four
6 | six
В реальных данных я буду иметь дело со многими миллионами строк в @R и около ста тысяч строк в @E.Так что я смотрю, могу ли я что-нибудь сделать, чтобы немного повысить производительность.
Редактировать: просто чтобы прояснить и подвести итог, есть кластерный pk-индекс для R с child_id, parent_id
идобавление индекса к @r.parent_id
также улучшит производительность соединения.
Есть ли что-то, что улучшит это?Немного после CTE с inner join 1=1
есть что-нибудь, что можно было бы улучшить здесь, это настолько хорошо, насколько это возможно?Есть ли какой-нибудь другой дизайн схемы, который я мог бы сделать, чтобы получить подобное сопоставление родитель-потомок с лучшей производительностью?