Имеются следующие таблицы (Oracle 10g):
catalog (
id NUMBER PRIMARY KEY,
name VARCHAR2(255),
owner NUMBER,
root NUMBER REFERENCES catalog(id)
...
)
university (
id NUMBER PRIMARY KEY,
...
)
securitygroup (
id NUMBER PRIMARY KEY
...
)
catalog_securitygroup (
catalog REFERENCES catalog(id),
securitygroup REFERENCES securitygroup(id)
)
catalog_university (
catalog REFERENCES catalog(id),
university REFERENCES university(id)
)
Каталог: 500 000 строк, catalog_university: 500 000, catalog_securitygroup: 1 500 000.
Мне нужно выбрать любые 50 строк из каталога с указанным корнем, упорядоченные по имени для текущего университета и текущей группы безопасности. Есть запрос:
SELECT ccc.* FROM (
SELECT cc.*, ROWNUM AS n FROM (
SELECT c.id, c.name, c.owner
FROM catalog c, catalog_securitygroup cs, catalog_university cu
WHERE c.root = 100
AND cs.catalog = c.id
AND cs.securitygroup = 200
AND cu.catalog = c.id
AND cu.university = 300
ORDER BY name
) cc
) ccc WHERE ccc.n > 0 AND ccc.n <= 50;
Где 100 - некоторый каталог, 200 - некоторая securitygroup, 300 - некоторый университет. Этот запрос возвращает 50 строк из ~ 170 000 за 3 минуты.
Но следующий запрос возвращает эти строки за 2 сек:
SELECT ccc.* FROM (
SELECT cc.*, ROWNUM AS n FROM (
SELECT c.id, c.name, c.owner
FROM catalog c
WHERE c.root = 100
ORDER BY name
) cc
) ccc WHERE ccc.n > 0 AND ccc.n <= 50;
Я строю следующие индексы: (catalog.id, catalog.name, catalog.owner), (catalog_securitygroup.catalog, catalog_securitygroup.index), (catalog_university.catalog, catalog_university.university).
План первого запроса (с использованием PLSQL Developer):
http://habreffect.ru/66c/f25faa5f8/plan2.jpg
План второго запроса:
http://habreffect.ru/f91/86e780cc7/plan1.jpg
Какие есть способы оптимизации имеющегося у меня запроса?