1

В настоящее время у меня есть запрос, который содержит самосоединение для запроса всех прямых и косвенных менеджеров сотрудника из таблицы, в которой хранится информация об организации компании, с помощью nested sets model. В SQL нотации числа двоеточие (например: 1) являются переменными:оптимизация представления для иерархических данных

select parent.empid, parent.depth from RelationshipMgr as node join 
RelationshipMgr as parent on node.lft between parent.lft and parent.rgt 
and node.empid = :1 order by parent.lft 

я могу тривиальным вернуть только идентификатор менеджера п уровней выше работника путем добавления parent.depth = node.depth - :2 либо условие объединения или предложение where (побочный вопрос: что быстрее?).

Проблема: Я пытаюсь превратить этот запрос в представление, и мне не очень повезло. Проблема в том, что большинство или все мои переменные находятся в состоянии соединения моего запроса. Мой текущий лучший план, чтобы разорвать эти части из в столбцы, которые я могу затем использовать где положение о том, когда я запрашиваю мнение, например, это:

select node.EmpID, parent.empid as MgrID, parent.depth as MgrDepth, 
node.depth - parent.depth as MgrRelativeAltitude from RelationshipMgr as node 
join RelationshipMgr as parent on node.lft between parent.lft and parent.rgt 

Вы можете увидеть, что я должен был изобрести MgrRelativeAltitude колонки чтобы найти идентификатор менеджера n уровней над сотрудником, но это вряд ли самая большая проблема. Я беспокоюсь, что это вызовет серьезные проблемы с производительностью, поскольку SQL Server, похоже, выполняет полное соединение, как указано условиями соединения, а затем фильтрует его по предложению where, а не разумно использует предложение where для ограничения соединения. Есть ли лучший способ создать представление? Должен ли я оставить это как вопрос и забыть о том, чтобы сделать вид? Получил бы я что-нибудь, сделав его хранимой процедурой вместо представления?

И, пожалуйста, не говорите, что «преждевременная оптимизация - это зло» ... это не преждевременно. Реализация, которую я заменяю, использовала нечто вроде сводного списка смежности, в котором была запись, связанная с сотрудником, когда-либо одним из его прямых и косвенных менеджеров ... наихудшие записи O (n^2) и, как ожидается, столкнулись с серьезными проблемами производительности, когда в иерархии было более 300000 сотрудников. Моя новая реализация вложенных наборов облегчит эти проблемы производительности, за исключением этого одного запроса ... если вы сделаете select * на предлагаемом представлении, результаты будут почти идентичны старой таблице, которую я пытаюсь заменить, и это касается меня очень много.

+2

Не видя таблицы, я не знаю, как структурированы данные (не знаю, что такое LFT/Rgt). Если вы находитесь на относительно новом SQL Server; я бы посмотрел на CTE для обработки вашего запроса - вы часто можете сделать что-то сложное намного легче читать.Эта страница на MSSQL Tips использует аналогичный пример, который может быть полезен http://www.mssqltips.com/tip.asp?tip=1520 – u07ch

+0

@ u07ch это модель гнездового набора садовых сортов ... там действительно есть Что-то особенное в моей структуре таблицы. «lft» и «rgt» - левый и правый столбцы (иногда также называемые вниз и вверх соответственно) техники вложенных множеств. Эти имена являются довольно стандартными, поскольку «left» и «right» являются зарезервированными словами в SQL. Я предоставил ссылку в своем вопросе, но вот еще один (прокрутите вниз до раздела на вложенных наборах): http://dev.mysql.com/tech-resources/articles/hierarchical-data.html – rmeador

ответ

0

Вы пытаетесь определить иерархическую взаимосвязь несмежных узлов. Как вы нашли, это относительно дорогостоящий расчет времени выполнения, просмотр или регулярный запрос. Вместо этого, если вы часто запускаете, я бы предложил создать то, что известно как bridge table, либо в качестве реальной таблицы, обновленной через триггер, либо в виде индексированного представления в SQL Server 2005+ (хотя и не пробовал подход с индексированным представлением). При этом вложенный набор обеспечивает превосходное время чтения по сравнению со списком смежности в любом случае.

Компромисс - это таблица со значительно большим количеством строк, чем источник, потому что она эффективно представляет отношения между всеми узлами, которые замедляют запись, поскольку она обновляет любые добавленные, удаленные или родительские идентификаторы узлов. В свою очередь, вы можете индексировать его и быстро получать время поиска. Оптимизация, если обновление моста доказывает, что узкое место доступа к нему осуществляется через хранимую процедуру, где мост служит в качестве кэша для частого запуска комбинаций входов, но вычисляет нечастые случаи во время выполнения. Чтобы сделать это определение, вам необходимо оценить скорость чтения и записи таблицы базового узла.

An overview of options for representing hierarchical data in a RDBMS is available here.

Смежные вопросы