Улучшение производительности просмотров - PullRequest
2 голосов
/ 31 января 2012

У меня есть представление, которое управляет полномочиями на уровне записей. Для этого мы будем называть его «AuthorityView». Он работает путем просмотра базовых таблиц, фактических данных, таблицы «Полномочия записи» и таблицы «Группы пользователей».

Для этого примера мы выбираем записи «Сотрудник». Существует базовая таблица «EmployeeData», которая содержит все данные, «EmployeeRecordAuthority», в которой указывается, какие группы пользователей имеют какой доступ к данным (чтение, чтение / запись, обновление, удаление и т. Д.) И «Группы пользователей» просто хранит, к каким группам принадлежат пользователи.

Представление использует довольно простое соединение, но обрабатывает много записей (~ 100 тыс. Записей сотрудников и ~ 3 м записей прав доступа). Конечным результатом является подмножество записей, которые пользователь может просматривать.

Проблема, с которой я столкнулся, заключается в том, что запросы к представлению без критериев очень медленные. Выполнение «select * from EmployeeAuthorityView» занимает около 6-7 минут, однако применение «top» к нему заставляет его работать так, как ожидается. «Выбор лучших 10000000 * из EmployeeAuthorityView» занимает всего несколько секунд.

Все соответствующие индексы существуют между таблицами и были перестроены.

Что может быть причиной замедления запросов? Почему быстрее выполнять запрос с указанным «верхним» пределом, даже если количество намного превышает количество записей в таблице?

Заранее спасибо.

1 Ответ

0 голосов
/ 31 января 2012

Разница в производительности, вероятно, из-за различных стратегий, которые оптимизатор запросов к базе данных использует для извлечения ваших данных.

Точная причина зависит от того, какую СУБД вы используете и как написан ее оптимизатор запросов, нопроблема возникает из концепции «представления без критериев» и выглядит примерно так:

Ваш EmployeeAuthorityView выглядит как объединение таблиц Data, RecordAuthority и UserGroups.Таким образом, само представление без каких-либо критериев фильтрации определяет теоретический набор, который является продуктом (внешним объединением) этих таблиц.Этот теоретический набор содержит 100 000 x 3 000 000 x U записей (U - размер вашей таблицы групп пользователей).Как только вы применяете некоторые критерии выбора, размер теоретического набора резко сокращается, но без каких-либо критериев он составляет триллионы записей (при условии, что ваша таблица UserGroups содержит более 3 строк).

Сколько записейэтот теоретический набор должен создавать СУБД, прежде чем он сможет дать вам полный буфер?Оптимизатор запросов учитывает несколько стратегий, в том числе (Стратегия A) создает все 300 млрд. Записей перед возвратом первого полного буфера в ваше приложение (Стратегия B), просто создавая записи по мере необходимости, возвращая буфер, заполненный вашему приложению, как только онесть так многоФакторы, влияющие на этот выбор, среди прочего, «в каком порядке нужно возвращать записи в ваше приложение».Использование «верхнего» предела приводит к тому, что порядок определяется по-другому, и в этом случае он выбирает что-то вроде стратегии B.

...