3

我的问题类似于To subselect or not to subselect? 但我想继续使用两个现有视图(因此我不想将子选择直接移动到视图逻辑中)。

(1.5 秒)

SELECT h.n
FROM   v_headers h 
WHERE  h.n >= (select 3000 from dual);

直接使用子选择中的值时查询速度很快:

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) )

列定义

  • 72 行
  • 57 行,master_dynamic_data = 'M'
  • column_def.col_id:唯一 1..100(有间隙)
  • column_def.col_name: c1, c2, c3,... (实际上是 20 个字符而不是 'cx')

qa_data:

  • 450k 行
  • 每个 qa_data.n 的平均行数为 112 行。(n 是从 1 到 4000)
  • qa_data.value 的平均长度为 18 个字符
4

1 回答 1

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 事件跟踪文件以了解正在发生的事情会很有趣。(给读者的作业。;-))

于 2014-11-05T14:34:28.770 回答