更新时间:2024-10-26 GMT+08:00

查询优化操作符

本章节主要介绍Teradata查询优化操作符的迁移语法。迁移语法决定了关键字/特性的迁移方式。

可以使用inToExists参数来配置从IN/NOT IN的到EXISTS/NOT EXISTS的迁移行为。

该参数的值默认为FALSE。要使用查询优化功能,需将该参数值设为TRUE。

迁移到GaussDB(DWS)的SQL查询,包含IN/NOT IN参数的Teradata查询已经优化并转换为EXISTS/NOT EXISTS运算符。IN/NOT IN操作符可对单列或多列使用。只有当IN/NOT IN语句存在于WHERE或ON子句中时,DSC才会迁移该语句。接下来以IN到EXISTS的转换为例(同样适用于NOT IN到NOT EXISTS的转换)。

IN到EXISTS的简单转换

在如下示例中,输入文件中提供了关键词IN。为进行优化,该工具在迁移过程中将其替换为EXISTS关键词。

  • 嵌套IN/NOT IN 的IN/NOT IN语句不支持迁移,迁移的脚本将失效。
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    UPDATE tab1
       SET b = 123
     WHERE b IN ('abc') 
       AND b IN ( SELECT  i 
                    FROM tab2 
                    WHERE j NOT IN (SELECT m 
                                     FROM tab3
                                   )
                 )
    ;
    

    迁移包含子查询的IN/NOT IN语句时,不支持迁移IN/NOT IN操作符和子查询(见示例)之间的注释。

    示例:

    1
    2
    3
    4
    5
    6
    7
    SELECT * 
      FROM categories 
     WHERE category_name
        IN --comment 
            ( SELECT category_name 
                FROM categories1 ) 
     ORDER BY category_name;
    
  • IN/NOT IN语句迁移,其中对象名称包含$和#
    • 如果TABLE名称或TABLE ALIAS以$(美元符号)开头,则工具不会对查询进行迁移。
      1
      2
      3
      SELECT Customer_Name
        FROM Customer_t $A
       WHERE Customer_ID IN( SELECT Customer_ID FROM Customer_t );
      
    • 如果COLUMN名称以#(hash)开头,则工具进行的查询迁移可能存在问题。
      1
      2
      3
      SELECT Customer_Name
        FROM Customer_t
       WHERE #Customer_ID IN( SELECT #Customer_ID FROM Customer_t );
      

输入:IN

1
2
3
4
SELECT ...
   FROM tab1 t
   WHERE t.col1 IN (SELECT icol1 FROM tab2 e)
 ORDER BY col1

输出

1
2
3
4
5
6
7
SELECT ...
   FROM tab1 t
   WHERE EXISTS (SELECT icol1
                    FROM tab2 e
                   WHERE icol1 = t.col1
                 )
 ORDER BY col1;

输入:IN,使用多列以及Aggregate函数

1
2
3
4
5
6
7
8
9
SELECT deptno, job_id, empno, salary, bonus
   FROM emp_t
  WHERE ( deptno, job_id, CAST(salary AS NUMBER(10,2))+CAST(bonus AS NUMBER(10,2)) ) 
                IN ( SELECT deptno, job_id, 
                      MAX(CAST(salary AS NUMBER(10,2))+CAST(bonus AS NUMBER(10,2)))
                        FROM emp_t 
                       WHERE hire_dt >= CAST( '20170101' AS DATE FORMAT 'YYYYMMDD' ) 
                       GROUP BY deptno, job_id )
    AND hire_dt IS NOT NULL;

输出

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
SELECT deptno, job_id, empno, salary, bonus
   FROM emp_t MAlias1
  WHERE EXISTS ( SELECT deptno, job_id, 
                            MAX(CAST(salary AS NUMBER(10,2))+CAST(bonus AS NUMBER(10,2)))
                      FROM emp_t 
                     WHERE hire_dt >= CAST( '20170101' AS DATE)
                           AND deptno  = MAlias1.deptno
                           AND job_id   = MAlias1.job_id
                     GROUP BY deptno, job_id 
                    HAVING MAX(CAST(salary AS NUMBER(10,2))+CAST(bonus AS NUMBER(10,2)))
                            = CAST(MAlias1.salary AS NUMBER(10,2))+CAST(MAlias1.bonus AS NUMBER(10,2)) )
    AND hire_dt IS NOT NULL;