我正在尝试从Oracle V$视图中获取一些信息
SELECT bpd.handle,bpd.media,bpd.copy#, bpd.bytes, bpd.session_key, bsjd.operation,bsjd.start_time, bsjd.end_time,bpd.completion_time,
bsd.controlfile_included
FROM v$backup_piece_details bpd
INNER JOIN v$rman_backup_subjob_details bsjd ON bpd.SESSION_KEY = bsjd.session_key
INNER JOIN v$backup_set_details bsd ON bpd.set_stamp = bsd.set_stamp AND bpd.set_count = bsd.set_count
INNER JOIN
(SELECT ibpd.session_key, count (ibpd.handle) count FROM v$backup_piece_details ibpd
INNER JOIN v$rman_backup_subjob_details rbsd ON IBPD.session_key = rbsd.SESSION_KEY
GROUP BY IBPD.session_key, IBPD.handle) hc
ON hc.session_key = bpd.SESSION_KEY
计划表输出
https://pastebin.com/raw/QrkzeHH7
如果我把
INNER JOIN
(SELECT ibpd.session_key, count (ibpd.handle) count FROM v$backup_piece_details ibpd
INNER JOIN v$rman_backup_subjob_details rbsd ON IBPD.session_key = rbsd.SESSION_KEY
GROUP BY IBPD.session_key, IBPD.handle) hc
ON hc.session_key = bpd.SESSION_KEY
查询在17秒内完成,而包含与临时表hc的内连接会导致查询在5分钟内完成频繁运行甚至会导致
ORA-01652: unable to extend temp segment by 128 in tablespace TEMP
我尝试添加/*+ use_hash(bpd hc) */
和/*+ use_hash(ibpd rbsd) */
作为提示,强制使用散列连接而不是嵌套循环,但问题仍然存在。
也不清楚为什么查询计划显示与recid列的左外连接,而我没有尝试使用它进行连接。
有人能解释一下查询计划吗?
3条答案
按热度按时间y1aodyip1#
使用字典查询时,你会遇到一堆视图(有时候是复杂的视图),视图合并可能会对计划造成严重破坏。我的建议是,假设你有正确的连接,并且这里没有任何多对多连接,那么就禁用视图合并(参见下面的两行提示,其中一行在子查询中):
其次,有时需要收集固定对象统计信息(
dbms_stats.gather_fixed_objects_stats
)。a9wyjsp72#
我无法访问您的视图,因此无法测试这是否会给予相同的输出,但您可以尝试使用一个分析
COUNT
函数,这样就不需要第二次连接表:也不清楚为什么查询计划显示与
recid
列的左外连接,而我没有尝试使用它进行连接。VIEW
只是一个具有预定义SQL语句的查询。当您从视图查询时,Oracle'的SQL引擎将重写您的语句,以便从视图查询的基础表中进行选择,如果视图所基于的语句在recid
列上使用LEFT OUTER JOIN
,则执行计划将显示recid
列上的LEFT OUTER JOIN
位于基础当您查询该视图时。fiddlef87krz0w3#
我同意关于提示和统计信息的说法,但似乎还有另一个问题,因为错误
ORA-01652: unable to extend temp segment by 128 in tablespace TEMP
。此错误意味着您选择的数据比临时表空间上的数据大,您应该选择较少的数据或增加表空间。您可以将查询拆分为两个