具有以下表格(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)
)目录:500000行,catalog_university: 500000,catalog_securitygroup: 1500000。
我需要从目录中选择任意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 -一些安全组,300 -一些大学。此查询在3分钟内从~170000返回50行。
但next查询在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
有什么方法可以优化我的查询?
发布于 2010-11-18 00:26:23
rownum的使用是错误的,会导致所有行都被处理。它将处理所有行,为它们分配一个行号,然后查找0到50之间的行。当您想要在解释计划中查找时是COUNT STOPKEY而不是仅仅计数
下面的查询应该是一个改进,因为它只会得到前50行...但是仍然有连接的问题需要考虑:
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
where rownum <= 50
) ccc WHERE ccc.n > 0 AND ccc.n <= 50;另外,假设这是一个网页或类似的东西,也许有一种更好的方法来处理这个问题,而不仅仅是再次运行查询来获取下一个页面的数据。
https://stackoverflow.com/questions/4205749
复制相似问题