我有一个需要太多的查询。 它正在运行一个10g的oracle实例。 TABLE_A有30.000.000行。 TABLE_B有300.000行。
SELECT A.F1, A.F2, B.F1
FROM ( SELECT A.F1, A.F2, B.F1
FROM TABLE_A A LEFT JOIN TABLE_B B ON A.ID_B = B.ID_B
WHERE A.F3 = ? AND A.F4 = ?
ORDER BY B.F1)
WHERE ROWNUM < 100
我尝试创建一个视图:
CREATE VIEW TABLE_B_SORTED AS SELECT * FROM TABLE_B ORDER BY F1
像那样修改查询
SELECT A.F1, A.F2, B.F1
FROM ( SELECT A.F1, A.F2, B.F1
FROM TABLE_A A LEFT JOIN TABLE_B_SORTED B ON A.ID_B = B.ID_B
WHERE A.F3 = ? AND A.F4 = ?
)
WHERE ROWNUM < 100
但订单不是经过处理的。
我也试图以这种方式修改查询
SELECT A.F1, A.F2, T.F1
FROM ( SELECT A.F1, A.F2, T.F1
FROM TABLE_A A LEFT JOIN (SELECT * FROM TABLE_B B ORDER BY B.F1 ) T ON A.ID_B = T.ID_B
WHERE A.F3 = ? AND A.F4 = ?
)
WHERE ROWNUM < 100
但订单不是经过处理的。
有什么建议吗?
Plan
SELECT STATEMENT ALL_ROWSCost: 8.943 Bytes: 2.871 Cardinality: 99
7 COUNT STOPKEY
6 VIEW MY_SCHEMA. Cost: 8.943 Bytes: 146.247 Cardinality: 5.043
5 SORT ORDER BY STOPKEY Cost: 8.943 Bytes: 226.935 Cardinality: 5.043
4 HASH JOIN OUTER Cost: 8.881 Bytes: 226.935 Cardinality: 5.043
2 TABLE ACCESS BY INDEX ROWID TABLE TABLE_A Cost: 8.117 Bytes: 172.725 Cardinality: 4.935
1 INDEX RANGE SCAN INDEX I_TABLE_A Cost: 27 Cardinality: 10.166
3 TABLE ACCESS FULL TABLE TABLE_B Cost: 758 Bytes: 2.791.520 Cardinality: 279.152
答案 0 :(得分:0)
如果您的查询花费太多时间,您应该创建可能在b.f1上创建升序索引。
此外,如果您正在执行LEFT JOIN,这意味着您可能在B中有NULL值。您想要它们是第一个还是最后一个?
可能你应该做得更好:
SELECT /*+ first_rows_100 */ -- do not hesitate to use Oracle hints!
a.f1, a.f2, b.f1
FROM table_b b
INNER JOIN table_a a
ON a.id_b = b.id_b
WHERE a.f3 = ? and a.f4 = ?
ORDER BY b.f1 ASC
此外,订购连接源完全是useles(第二和第三个查询)。 JOINing永远不会保证结果行保持在源表中找到它们的顺序。