2012-01-31 2 views
2

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

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

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

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

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

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

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

+0

Будет ли это Oracle, MySQL, SQL Server или другие РСУБД? –

ответ

0

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

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

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

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