Я использую MS SqlServer 2008. И у меня есть таблица «Пользователи». Эта таблица имеет идентификатор ключевого поля bigint. А также поле Parents varchar, которое кодирует всю цепочку родительских идентификаторов пользователя. Например:Иерархический SQL-запрос-запрос
пользователя стол:
ID | Parents
1 | null
2 | ..
3 | ..
4 | 3,2,1
Здесь пользователь 1 не имеет родителей и пользователь 4 имеет цепь родителей 3-> 2-> 1. Я создал функцию, которая анализирует поле «Родители» пользователя и возвращает таблицу результатов с идентификаторами пользователя bigint.
Теперь мне нужен запрос, который будет выбирать и присоединять идентификаторы некоторых запрашиваемых пользователей и их родителей (порядок пользователей и их родителей не важен). Я не эксперт по SQL, поэтому все, что я мог придумать, следующее:
WITH CTE AS(
SELECT
ID,
Parents
FROM
[Users]
WHERE
(
[Users].Name = 'John'
)
UNION ALL
SELECT
[Users].Id,
[Users].Parents
FROM [Users], CTE
WHERE
(
[Users].ID in (SELECT * FROM GetUserParents(CTE.ID, CTE.Parents))
))
SELECT * FROM CTE
И в основном это работает. Но производительность этого запроса очень плохая. Я считаю, ГДЕ .. IN .. выражение здесь - горло бутылки. Насколько я понимаю, вместо того, чтобы просто присоединяться к первому подзапросу CTE (идентификаторы найденных пользователей) с результатами GetUserParents (идентификаторы родителей пользователей), он должен перечислить всех пользователей в таблице Users и проверить, является ли каждый из них частью результат функции (и, судя по плану выполнения), Sql Server делает отчетливый порядок результата для повышения производительности оператора WHERE .. IN .., который логичен сам по себе, но в целом не требуется для моей цели. 70% времени выполнения запроса). Поэтому мне интересно, как этот запрос может быть улучшен или кто-то может предложить другой подход для решения этой проблемы?
Спасибо за помощь!
Что делает 'GetUserParents()' do? – DavidG
Он получает в качестве идентификатора параметра пользователя и его varchar-представление родительских идентификаторов. И возвращает таблицу проанализированных родительских идентификаторов: – Kreol
О, я вижу. Лично я бы не использовал столбец varchar и создал другую таблицу со строкой для каждого родителя. Таким образом, вам не нужна функция для синтаксического анализа строки. – DavidG