【发布时间】:2012-09-13 03:58:47
【问题描述】:
我正在使用 Oracle 10g,并且我有一个连接两个大表(数百万条记录)的视图。我正在尝试为用户选择有限的数据“样本”,如下所示:
select * from VIEW_NAME where ROWNUM < 5;
它很慢,我认为不应该,因为我只需要几行结果,所以Oracle不应该计算全连接。
要求是用户应该能够以交互方式指定返回的行数(结果中的哪些行并不重要)。有什么办法可以做到这一点? (使用 rownum 或其他方法)
(我可以更改视图定义或构建最终 SQL 的方式,但据我所知,我无法将有关所需行数的信息动态传递给视图)
编辑:视图定义非常简单,如下所示:
CREATE OR REPLACE VIEW VIEW_NAME AS
(
select
e.id as ID,
e.somefield as something,
... (some similar selects from e)
c.field as anotherthing,
... (lots of other fields from c)
from SCHEMA.TABLE1 e
inner join SCHEMA.TABLE2 c on e.key = c.key
)
解释计划提到了两个表的全表访问,这并不奇怪,因为只返回前几行应该不会花费很长时间。
EDIT2:这是完整的计划
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2644394598
----------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 1252 | | 43546 (1)| 00:08:43 | | | | | |
|* 1 | COUNT STOPKEY | | | | | | | | | | | |
| 2 | PX COORDINATOR | | | | | | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10002 | 696K| 207M| | 43546 (1)| 00:08:43 | | | Q1,02 | P->S | QC (RAND) |
|* 4 | COUNT STOPKEY | | | | | | | | | Q1,02 | PCWC | |
|* 5 | HASH JOIN BUFFERED | | 696K| 207M| 49M| 43546 (1)| 00:08:43 | | | Q1,02 | PCWP | |
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
| 6 | BUFFER SORT | | | | | | | | | Q1,02 | PCWC | |
| 7 | PX RECEIVE | | 696K| 90M| | 5137 (1)| 00:01:02 | | | Q1,02 | PCWP | |
| 8 | PX SEND HASH | :TQ10000 | 696K| 90M| | 5137 (1)| 00:01:02 | | | | S->P | HASH |
| 9 | TABLE ACCESS FULL| TABLE1 | 696K| 90M| | 5137 (1)| 00:01:02 | | | | | |
| 10 | PX RECEIVE | | 892K| 149M| | 5260 (1)| 00:01:04 | | | Q1,02 | PCWP | |
| 11 | PX SEND HASH | :TQ10001 | 892K| 149M| | 5260 (1)| 00:01:04 | | | Q1,01 | P->P | HASH |
| 12 | PX BLOCK ITERATOR | | 892K| 149M| | 5260 (1)| 00:01:04 | 1 | 140 | Q1,01 | PCWC | |
| 13 | TABLE ACCESS FULL| TABLE2 | 892K| 149M| | 5260 (1)| 00:01:04 | 1 | 140 | Q1,01 | PCWP | |
----------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------
1 - filter(ROWNUM<5)
4 - filter(ROWNUM<5)
5 - access("E"."KEY"="C"."KEY")
27 rows selected.
【问题讨论】:
-
视图到底在做什么?您可以发布视图的来源吗?该语句的查询计划是什么? “非常慢”对您意味着什么 - 您是说返回结果需要几个小时吗?分钟? 5 秒什么时候你认为应该是亚秒级响应?
-
测试数据库中非常慢的是 15 秒,但在生产数据库中(我无法访问那里)有 3 倍多的数据。我会尽快为这个问题添加更多信息。
-
你能发布实际的查询计划吗?它是在做哈希连接吗?嵌套循环连接?当您说“来自 e 的类似选择”时,您是在谈论内联查询吗?或者只是引用
e中的列? -
它正在做一个哈希连接,它只是简单地引用 e 中的列,没有隐藏的子选择或其他技巧......我正在尝试发布整个计划。
-
iirc - 在将 rownum 标准应用于返回的结果集之前,rownum 始终计算完整的结果集。换句话说,通过使用 ROWNUM 进行限制,您不会看到任何性能提升。
标签: database performance oracle view rownum