оптимизация представления для иерархических данных - PullRequest
1 голос
/ 03 августа 2010

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

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

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

1 Ответ

0 голосов
/ 02 февраля 2011

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

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

Обзор вариантов представления иерархических данных в СУБД доступен здесь .

...