【问题标题】:Oracle convert DECODE to PIVOT or force use of indexOracle 将 DECODE 转换为 PIVOT 或强制使用索引
【发布时间】:2013-06-11 11:47:33
【问题描述】:

我有一个非常复杂的 SQL 视图定义,它已被继承,需要更改以提高性能。它采用基于外键的记录列表并将返回的行显示为列。

因此:- 使用 RANK 选择的数据

ID RANK DKEY RECORD1 RECORD2 RECORD3
1  1    1    003     Rob     Emmerry
1  2    2    004     Sue     Emmerry

返回

ID REC11 REC12 REC13   REC21 REC22 REC23
1  003   Rob   Emmerry 004   Sue   Emmerry

每个返回的行有 37 列数据重复,最多 5 列。 使用

SELECT ID,
MIN(DECODE(ranking,1,RECORD1, NULL)) AS REC11
MIN(DECODE(ranking,1,RECORD2, NULL)) AS REC12
MIN(DECODE(ranking,1,RECORD3, NULL)) AS REC13
MIN(DECODE(ranking,1,RECORD4, NULL)) AS REC14
MIN(DECODE(ranking,1,RECORD5, NULL)) AS REC15
MIN(DECODE(ranking,1,RECORD6, NULL)) AS REC16
MIN(DECODE(ranking,2,RECORD1, NULL)) AS REC21
MIN(DECODE(ranking,2,RECORD2, NULL)) AS REC22
MIN(DECODE(ranking,2,RECORD3, NULL)) AS REC23
MIN(DECODE(ranking,2,RECORD4, NULL)) AS REC24
MIN(DECODE(ranking,2,RECORD5, NULL)) AS REC25
MIN(DECODE(ranking,2,RECORD6, NULL)) AS REC26
FROM 
(
SELECT ID, RANK () OVER (PARTITION BY id ORDER BY dkey) ranking,
RECORD1,
RECORD2,
RECORD3,
RECORD4,
RECORD5,
RECORD6
FROM TABLEA
JOIN
 (SELECT ID, DKEY, RECORD4, RECORD5, RECORD6
  FROM TABLEB
 ) ON TABLEB.DKEY = TABLEA.DKEY AND TABLEB.ID = TABLEA.ID
)
GROUP BY ID;

当使用解释计划并对具有索引的 DKEY 字段进行过滤时,该索引可能会被忽略,因为 min/decode 语句。

所以我想用 PIVOT 重写它,但不知道如何开始。

关于我如何做的任何想法 a) 获取查询以使用索引 b) 使用 PIVOT 重写

第一个选项显然更可取。

谢谢 克雷格

更新

这里是一些示例数据,展示了我的表格。

    Table 1             
    DKEY PID RECORD1 RECORD2 RECORD3
    1    1   3       Rob     Emmerry
    2    1   4       Sue     Emmerry
    3    1   4       Jan     Morris
    4    1   4       Sue     Pye
    5    1   4       Jane    Taylor

    Table 2             
    CID DKEY RECORD10       
    1   3    A      
    2   3    D      
    3   3    G      
    4   3    J      
    5   4    A      
    6   5    A      
    7   5    D      
    8   6    A      
    9   6    D      
    10  6    G      
    11  7    A      
    12  7    D      
    13  7    G      
    14  7    J      
    15  7    M      

    Table 3             
    QID DKEY RECORD3        
    1   3    C      
    2   6    C      
    3   6    F      
    4   7    C      
    5   7    F      

所以表 2 和表 3 使用 DKEY 链接到表 1 如果我们以 DKEY=3 为例,我希望看到这个:-

    PID DKEY REC1 REC2 REC3   REC4 REC5 REC6 REC7 REC8 REC9 REC10 REC11 REC12 REC13
    1   3    4    Jan  Morris A    D    G    J    NULL C    NULL  NULL  NULL  NULL

表 2 和表 3 中的每一个最多可以有 5 行。表 1 中的字段 PID、DKEY、REC1-REC3,表 2 中的 REC4-REC8 字段和表 3 中的其余字段。表 1 中的其他记录会简单地继续在行上,所以在 REC13、DKEY=4 等之后。

希望这是有道理的。

【问题讨论】:

  • 是的,很抱歉应该提到这一点,11g 正确。
  • 另一个与我的性能问题有关的说明。如何在不多次阅读视图的情况下加入 DECODE PIVOTS。
  • 另一个与我的性能问题有关的说明。如何在不多次阅读视图的情况下一起加入 DECODE PIVOTS。让我试着解释一下。我有上面的 PIVOT,它将 1 位经理说和他的所有员工(最多 5 位)聚集到 1 行。然后我有 3 个其他表,它们分别针对这 5 名员工中的每一个,这些表也可以有 5 条记录。这 3 个表也以与上表相同的方式进行 PIVOTED。我如何在不阅读这 3 个额外的 PIVOTS 5 次的情况下将它们加入原始 PIVOT?我会附上我们目前正在做的事情。
  • 您可以使用表格中的一些示例数据来编辑您的原始帖子吗?

标签: oracle indexing oracle11g pivot decode


【解决方案1】:
SELECT
    ID,
    MIN(DECODE(ranking,1,RECORD1, NULL)) AS REC11,
    MIN(DECODE(ranking,1,RECORD2, NULL)) AS REC12,
    MIN(DECODE(ranking,1,RECORD3, NULL)) AS REC13,
    MIN(DECODE(ranking,1,RECORD4, NULL)) AS REC14,
    MIN(DECODE(ranking,1,RECORD5, NULL)) AS REC15,
    MIN(DECODE(ranking,1,RECORD6, NULL)) AS REC16,
    MIN(DECODE(ranking,2,RECORD1, NULL)) AS REC21,
    MIN(DECODE(ranking,2,RECORD2, NULL)) AS REC22,
    MIN(DECODE(ranking,2,RECORD3, NULL)) AS REC23,
    MIN(DECODE(ranking,2,RECORD4, NULL)) AS REC24,
    MIN(DECODE(ranking,2,RECORD5, NULL)) AS REC25,
    MIN(DECODE(ranking,2,RECORD6, NULL)) AS REC26
FROM 
(
    SELECT /*+ INDEX(tablea tablea_index) */
        ID,
        RANK () OVER (PARTITION BY id ORDER BY dkey) ranking,
        RECORD1,
        RECORD2,
        RECORD3,
        RECORD4,
        RECORD5,
        RECORD6
    FROM TABLEA
    JOIN TABLEB
    -- was: ON TABB.DKEY = TABLEA.DKEY AND TABB ON TABB.ID = TABLEA.ID
    ON  TABLEB.DKEY = TABLEA.DKEY
    AND TABLEB.ID   = TABLEA.ID
)
GROUP BY ID;

【讨论】:

  • 感谢确实强制使用索引,但我忘了提到还有一个内部连接,我已经更新了详细信息。我的印象是连接条件也应该导致索引被使用。两个连接都针对主键和辅助索引字段。但我只能得到第一个表主索引被使用。
  • 这是新的:ON TABB.DKEY = TABLEA.DKEY AND TABB ON TABB.ID = TABLEA.ID
  • 对不起,我的错误把连接条件写错了。我已经尝试过了,它仍然无法正常工作。如果我只是尝试使用连接的子选择语句,则使用两个索引。
猜你喜欢
  • 2021-08-26
  • 1970-01-01
  • 1970-01-01
  • 2020-10-07
  • 1970-01-01
  • 2015-09-27
  • 2018-04-02
  • 1970-01-01
  • 2013-06-13
相关资源
最近更新 更多