查询:
SELECT A.USER_ID, A.ROLE_ID, C.SUBGROUP, MAX(A.STATUS_ID)
FROM USER_ROLE A, USER B, ROLE C
WHERE A.ROLE_ID = C.ROLE_ID
AND C.GROUP_ID = 3
AND A.USER_ID = B.USER_ID
AND B.TEMPLATE_IND = 'N'
AND B.ONAP_PARTCODE IS NULL
AND A.PARTCODE ='005'
GROUP BY A.PARTCODE,
A.USER_ID,
A.ROLE_ID,
C.SUBGROUP;
解释计划:
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Co
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 74 |
| 1 | HASH GROUP BY | | 1 | 74 |
| 2 | NESTED LOOPS | | 1 | 74 |
| 3 | NESTED LOOPS | | 56 | 3024 |
| 4 | TABLE ACCESS BY INDEX ROWID| ROLE | 8 | 240 |
|* 5 | INDEX RANGE SCAN | N_ROLE_IDX2 | 8 | |
| 6 | TABLE ACCESS BY INDEX ROWID| USER_ROLE | 7 | 168 |
|* 7 | INDEX RANGE SCAN | N_USER_ROLE_IDX6 | 7 | |
| 8 | REMOTE | MV_PT_USER | 1 | 20 |
--------------------------------------------------------------------------------
答案 0 :(得分:4)
我重写了你的查询以使用ANSI-92语法:
SELECT A.USER_ID, A.ROLE_ID, C.SUBGROUP, MAX(A.STATUS_ID)
FROM USER_ROLE a
JOIN USER b ON b.user_id = a.user_id
AND b.template_ind = 'N'
AND b.onap_partcode IS NULL
JOIN ROLE c ON c.role_id = a.role_id
AND c.group_id = 3
WHERE a.PARTCODE ='005'
GROUP BY a.USER_ID, a.ROLE_ID, c.SUBGROUP, a.PARTCODE;
对suggest the following covering indexes来说,这不是更快,对我来说更清楚:
CREATE INDEX ur_idx ON USER_ROLE (user_id, role_id, partcode) COMPUTE STATISTICS;
CREATE INDEX u_idx ON USER (user_id, template_ind) COMPUTE STATISTICS;
CREATE INDEX r_idx ON ROLE (role_id, group_id) COMPUTE STATISTICS;
答案 1 :(得分:2)
计划中的ROWS估计以1结束,而不是在1700附近。 MV_PT_USER上的“远程”操作很有意思。看起来优化器假设该操作将返回一行(或者可能为零),即使没有过滤。
收集该对象的一些统计信息可能会告诉oracle它可能返回多少行,并建议与优化器不同的计划。
答案 2 :(得分:0)
如果不了解有关您的表架构和索引的详细信息,那么很难给出正确的建议。
它可能没什么用,但我确实看到你的GROUP BY子句中的A.PARTCODE不需要。
答案 3 :(得分:0)
您的查询需要30秒。现在我们需要知道这些30秒花在哪里。提供的信息几乎没有,所以是时候跟踪查询的运行了。
以下是有关如何收集所需信息的一些快速信息:http://forums.oracle.com/forums/thread.jspa?messageID=1812597
此致 罗布。
答案 4 :(得分:0)
我认为你最好研究什么是内连接,右连接和左连接
如果所有表都有公共字段而不是null,那么您可以考虑处理最少行数的内部连接