避免多次查找并提高性能

时间:2016-04-01 11:31:10

标签: oracle postgresql talend datastage sql-data-services

我有一个案例,我需要进行多次连接(查找),如下面的查询。给出了示例场景。

我有大约200个CAT_CODE。我认为很少的解决方案,我把它列为案例。是否有任何不同的方式来编写SQL查询以获得更好的性能?或ETL工具中的任何更好的方法?

主要表格(PRIM):

NUM     CAT1_CODE   CAT2_CODE   CAT3_CODE
A          1           y           q     
B          2           e           a     
C          3           s           z    

辅助表格(LOV):

CATEGORY    COLUMN_LKP        EXT_CODE
CAT1_CODE       1                AB
CAT1_CODE       2                CD
CAT1_CODE       3                HI
CAT2_CODE       y                JL
CAT2_CODE       e                QD
CAT2_CODE       s                AH
CAT3_CODE       q                CD
CAT3_CODE       a                MS
CAT3_CODE       z                EJ

CASE-1:通过SQL:

我写了一个简单的查询来完成这项任务。你认为,这是正确的方法吗?还有其他方法可以改善这个查询吗?现在,我正在使用Oracle和Postgres。

SELECT 
NUM,
(SELECT EXT_CODE FROM TEST_LOV 
WHERE CATEGRY='CAT1_CODE' AND COLUMN_LKP=A.CAT1_CODE) CAT1,
(SELECT EXT_CODE FROM TEST_LOV 
WHERE CATEGRY='CAT2_CODE' AND COLUMN_LKP=A.CAT2_CODE) CAT2,
(SELECT EXT_CODE FROM TEST_LOV 
WHERE CATEGRY='CAT3_CODE' AND COLUMN_LKP=A.CAT3_CODE) CAT3 
FROM 
TEST_PRIM A

必需的输出:

NUM CAT1    CAT2    CAT3
A    AB      JL      CD
B    CD      QD      MS
C    HI      AH      EJ

CASE-2:ETL:

同样的情况可以通过ETL完成。我们需要使用查找来完成这项工作。

情境-1:

       LOV(CAT1_CODE)  LOV(CAT2_CODE)   LOV(CAT3_CODE)
           |                |                  |
           |                |                  |
PRIM---->LOOKUP---------->LOOKUP------------>LOOKUP-------->TARGET

我不认为,这是正确的做法。我们有200个代码,我们不能使用200个查找。是否有更好的方法来处理ETL(Datastage,Talend,BODS)中具有更好性能的方法?

情境-2:

透过PRIM(将CAT1_CODE,CAT2_CODE,CAT3_CODE列转换为行),如下所示并进行一次查找。但是,旋转需要很长时间,因为我们有大约6亿和200列的数据。

NUM     CATGRY           CODE
A       CAT1_CODE          1
A       CAT1_CODE          y
A       CAT1_CODE          q
B       CAT2_CODE          2
B       CAT2_CODE          e
B       CAT2_CODE          a 
C       CAT3_CODE          3
C       CAT3_CODE          s
C       CAT3_CODE          z 

请告诉我一些处理这种方法的最佳方法。可以通过ETL或通过sql。提前谢谢。

1 个答案:

答案 0 :(得分:1)

您可以使用LATERAL keyword来制作您正在寻找的魔法。

以下代码可以提供帮助:

SELECT 
  NUM, 
  MAX(ext_code) FILTER (WHERE c.CATEGORY='CAT1_CODE') AS CAT1,
  MAX(ext_code) FILTER (WHERE c.CATEGORY='CAT2_CODE') AS CAT2,
  MAX(ext_code) FILTER (WHERE c.CATEGORY='CAT3_CODE') AS CAT3
FROM TEST_PRIM a
  CROSS JOIN LATERAL (
    SELECT * 
    FROM TEST_LOV b 
    WHERE 
      (a.CAT1_CODE=b.COLUMN_LKP AND B.CATEGORY = 'CAT1_CODE')
      OR (a.CAT2_CODE=b.COLUMN_LKP AND B.CATEGORY = 'CAT2_CODE')
      OR (a.CAT3_CODE=b.COLUMN_LKP AND B.CATEGORY = 'CAT3_CODE')
    ) c
 GROUP BY NUM
 ORDER BY NUM; 

<强> 输出

 num | cat1 | cat2 | cat3
-----+------+------+------
 A   | AB   | JL   | CD
 B   | CD   | QD   | MS
 C   | HI   | AH   | EJ