我的问题类似于To subselect or not to subselect?,但我想继续使用现有的两个视图(因此我不想将子视图直接移动到视图逻辑中)。
慢(1.5秒)
SELECT h.n
FROM v_headers h
WHERE h.n >= (select 3000 from dual);
直接使用subselect中的值时,查询快速:
SELECT h.n
FROM v_headers h
WHERE h.n >= 3000;
更多细节:n不是唯一的,它的值在0到4000之间;对于每个n存在大约50行。来自不同行的11个值沿着n轴旋转到列中。
有没有提取视图后面的选择(或修改表)的解决方案?优化器暗示可能吗?
首先是慢速的,第二个是快速的:
LE:我简化了查询。
由于@ nop77svk,简化的查询工作得很快。更复杂的查询还没有(还):
快速
with xyz$ as (select 3986 as n from dual)
SELECT h.hw_number
FROM xyz$ X
JOIN v_headers h
ON h.hw_number >= x.n
缓慢(并且仍然有些简化):
with xyz$ as ((SELECT nvl(MAX(n), 0) AS n
FROM (SELECT h.hw_number AS n,
Rank() OVER(ORDER BY h.hw_number DESC) rnk
FROM x_data h
GROUP BY h.hw_number)
WHERE rnk = 50))
SELECT h.hw_number
FROM xyz$ X
JOIN v_headers h
ON h.hw_number >= x.n;
有关视图v_headers的更多详细信息:
WITH s AS
(
SELECT a.n,
b.col_name,
a.value,
b.col_id
FROM qa_data a
JOIN column_def b
ON b.col_id = a.col_id
WHERE b.master_dynamic_data = 'M' )
SELECT "n","c1","c2","c3","c4","c4","c5","c6","c7","c8","c9","c10"
FROM s PIVOT( Max(value)
keep(dense_rank first ORDER BY col_id) FOR col_name IN (
'c1' c1,
'c2' c2,
'c3' c3,
'c4' c4,
'c5' c5,
'c6' c6,
'c7' c7,
'c8' c8,
'c9' c9,
'c10' c10,
'c11' c11) )
COLUMN_DEF
qa_data:
答案 0 :(得分:1)
在简化版中......
SELECT --+ leading(X) use_hash(H)
H.n
FROM (select 3000 as n from dual) X
JOIN v_headers H
ON H.n >= X.n
;
... >= 3000
谓词被正确解析为访问谓词,这会导致Exadata存储索引启动。
但是,在完整版中,必须强制将谓词传播到内部视图,这似乎不会发生。快速检查测试设置显示,将这样的谓词(对于计算值,而不是常量值)传播到连接视图运行正常,但将谓词传播到透视连接视图则不会。
当使用预先计算n
的值而不是使用内联视图的(确定性)函数时,情况也是如此 - 谓词不会被推送到透视连接视图(在12.1.0.2上尝试过) )。
看到10053事件跟踪文件以了解发生了什么将会很有趣。 (为读者做作业。; - ))