Wil*_*son 5 performance oracle subquery query-performance
我有两个疑问:
1)此查询有一个 ROWNUM 列(执行需要 20 秒):
SELECT
ROWNUM
,ROAD_ID
,VERTEX_INDEX
,SDE.ST_X(ST_POINT) AS X
,SDE.ST_Y(ST_POINT) AS Y
FROM
(
SELECT
ROWNUM
,a.ROAD_ID
,b.NUMBERS VERTEX_INDEX
,SDE.ST_PointN(a.SHAPE, b.NUMBERS) AS ST_POINT
FROM ENG.ROAD a
CROSS JOIN ENG.NUMBERS b
WHERE b.NUMBERS <= SDE.ST_NUMPOINTS(a.SHAPE)
)
--removed to do explain plan: ORDER BY ROAD_ID, VERTEX_INDEX
-------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5996 | 322K| | 262 (1)| 00:00:01 |
| 1 | COUNT | | | | | | |
| 2 | VIEW | | 5996 | 322K| | 262 (1)| 00:00:01 |
| 3 | COUNT | | | | | | |
| 4 | MERGE JOIN | | 5996 | 1545K| | 262 (1)| 00:00:01 |
| 5 | INDEX FULL SCAN | R23715_SDE_ROWID_UK | 30 | 90 | | 1 (0)| 00:00:01 |
|* 6 | SORT JOIN | | 3997 | 1018K| 2392K| 261 (1)| 00:00:01 |
| 7 | TABLE ACCESS FULL| ROAD | 3997 | 1018K| | 34 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
" 6 - access(""B"".""NUMBERS""<=""SDE"".""ST_NUMPOINTS""(""A"".""SHAPE""))"
" filter(""B"".""NUMBERS""<=""SDE"".""ST_NUMPOINTS""(""A"".""SHAPE""))"
Run Code Online (Sandbox Code Playgroud)
2)此查询没有 ROWNUM 列(执行需要 40 秒):
SELECT
RDSEC
,VERTEX_INDEX
,SDE.ST_X(ST_POINT) AS X
,SDE.ST_Y(ST_POINT) AS Y
FROM
(
SELECT
a.RDSEC
,b.NUMBERS VERTEX_INDEX
,SDE.ST_PointN(a.SHAPE, b.NUMBERS) AS ST_POINT
FROM INFRASTR.STRLN_ROUTE_SIMPLIFY a
CROSS JOIN INFRASTR.NUMBERS b
WHERE b.NUMBERS <= SDE.ST_NUMPOINTS(a.SHAPE)
)
--removed to do explain plan: ORDER BY RDSEC, VERTEX_INDEX
----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5996 | 1545K| | 262 (1)| 00:00:01 |
| 1 | MERGE JOIN | | 5996 | 1545K| | 262 (1)| 00:00:01 |
| 2 | INDEX FULL SCAN | R23715_SDE_ROWID_UK | 30 | 90 | | 1 (0)| 00:00:01 |
|* 3 | SORT JOIN | | 3997 | 1018K| 2392K| 261 (1)| 00:00:01 |
| 4 | TABLE ACCESS FULL| ROAD | 3997 | 1018K| | 34 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
" 3 - access(""B"".""NUMBERS""<=""SDE"".""ST_NUMPOINTS""(""A"".""SHAPE""))"
" filter(""B"".""NUMBERS""<=""SDE"".""ST_NUMPOINTS""(""A"".""SHAPE""))"
Run Code Online (Sandbox Code Playgroud)
为什么在第一个查询中添加 ROWNUM 会提高性能?如果有的话,我会认为它会减慢速度。
上有查询的一些背景资料在这里。
更新:
我错误地认为我无法运行解释计划。我仅使用 GIS 软件来运行查询;不是 SQLplus(或任何其他适当的数据库软件)。
我被告知否则;我现在使用 DBMS_XPLAN 来运行解释计划。
Jus*_*ave 11
发布查询的两个版本的查询计划(以及另一个版本的确切 SQL,只是为了清楚起见)肯定会有所帮助。我猜想这样做会证明以下理论。但是,如果没有它,我可以猜测可能会发生什么,但我无法确定。
通常,数据库可以按照它认为最有效的任何顺序自由地评估查询的元素。这可能意味着它首先完整地执行内联视图,然后应用包括调用SDE.ST_X
和SDE.ST_Y
函数的外部投影。或者它可能意味着它转换了查询,以便为每一行调用外部函数,并且外部谓词(如果有)被推送到内联视图中。
如果rownum
向内联视图添加,在任何当前版本的 Oracle 中,都会阻止优化器将逻辑推入内联视图,因为优化器无法确定它不会影响返回的结果。从理论上讲,未来优化器的某些版本可能足够聪明,可以确定评估内联视图中的SDE.ST_X
和SDE.ST_Y
函数实际上不会改变rownum
生成的 ,但推动order by
可能会改变结果,因此将允许某些转换和其他转换被拒绝。但是在目前,添加一个rownum
行为基本上可以强制优化器的手“按原样”离开内联视图。
最有可能的是,优化器对各种函数调用的成本和选择性的估计是关闭的。如果该b.NUMBERS <= SDE.ST_NUMPOINTS(a.SHAPE)
函数的开销低于优化器的预期,并且过滤掉的数据比优化器预期的多得多,则它可能会决定在每一行上调用SDE.ST_X
和SDE.ST_Y
比先过滤所有数据然后再通过它更有效调用函数并进行排序。理想情况下,您可以为优化器提供有关各种功能的更好统计信息,以便它可以提出更有效的计划而无需添加rownum
(特别是因为该技巧可能会在将来的某个时刻突然停止工作)但我我当然知道添加一个rownum
如果我需要快速和肮脏的修复,像这样一两次(以及解释原因的评论)。