在WHERE子句中改进包含数百个字符串的Netezza SQL查询

时间:2017-11-21 15:01:05

标签: sql netezza

我有一个带有WHERE子句的Netezza查询,该子句包含数百个潜在的字符串。我很惊讶它运行,但它需要时间来完成,偶尔会出错('交易由客户回滚')。这是我查询的伪代码版本。

SELECT
    TO_CHAR(X.I_TS, 'YYYY-MM-DD') AS DATE,
    X.I_SRC_NM AS CHANNEL,
    X.I_CD AS CODE,
    COUNT(DISTINCT CASE WHEN X.I_FLG = 1 THEN X.UID ELSE NULL) AS WIDGETS

FROM
    (SELECT
        A.I_TS,
        A.I_SRC_NM,
        A.I_CD,
        B.UID,
        B.I_FLG

    FROM
        SCHEMA.DATABASE.TABLE_A A
        LEFT JOIN SCHEMA.DATABASE.TABLE_B B ON A.UID = B.UID

    WHERE
        A.I_TS BETWEEN '2017-01-01' AND '2017-01-15'
        AND B.TAB_CODE IN ('00AV', '00BX', '00C2', '00DJ'...
                           ...
                           ...
                           ...
                           ...
                           ...
                           ...
                           ...)
    ) X

GROUP BY
    X.I_TS,
    X.I_SRC_NM,
    X.I_CD
;

在我的查询中,我将B.TAB_CODE上的结果限制为大约1,200个值(超过10k)。我真的很惊讶它一点都有效,但它大部分时间都有效。

有没有更有效的方法来解决这个问题?

3 个答案:

答案 0 :(得分:3)

如果IN子句变得过于繁琐,您可以在多个部分进行查询。创建一个包含 TAB_CODE 集的临时表,然后在JOIN中使用它。

WITH tab_codes(tab_code) AS (
 SELECT '00AV' 
 UNION ALL
 SELECT '00BX' 
 --- etc ---
)
SELECT
  TO_CHAR(X.I_TS, 'YYYY-MM-DD') AS DATE,
  X.I_SRC_NM AS CHANNEL,
  --- etc ---
  INNER JOIN tab_codes Q ON B.TAB_CODES = Q.tab_code

如果您想进一步提高性能,请考虑使用真正的临时表(CTAS

答案 1 :(得分:1)

我们已经看到CTAS将原始表格“更便宜”到另一个,在主要条件下分发,然后再查询该表的情况。

答案 2 :(得分:0)

  1. 如果我正确猜测,X.I_TS实际上是一个'时间戳',因此我希望它每天包含许多不同的值。你能证实吗? 如果我是对的,那么查询可能会从将“由X.I._TS分组,......”更改为“分组1,......”

  2. 此外,'Count(Distinct Case ...'永远不会返回除1或NULL之外的任何内容。你能确认一下吗? 如果我是对的,你可以通过将它更改为'MAX(案例......'

  3. 来摆脱昂贵的'DISTINCT'

    你能跟我来吗:)。