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

改进了在WHERE子句中包含数百个字符串的Netezza SQL查询,sql,netezza,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

我有一个带有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_代码的结果限制在超过10k的值中的1200个左右。老实说,我很惊讶它能起作用,但大多数时候都能起作用

有没有更有效的方法来处理这个问题?

如果IN子句变得太麻烦,您可以将查询分为多个部分。创建一个包含TAB_代码集的临时表,然后在联接中使用它

如果你想进一步提高性能,考虑使用一个真正的临时表CTAs

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

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

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

此外,“CountDistinct Case…”不能返回除1或NULL以外的任何内容。你能证实吗? 如果我是对的,你可以通过把它改成“MAXCase…”来摆脱昂贵的“DISTINCT”

你能跟我来吗

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

此外,“CountDistinct Case…”不能返回除1或NULL以外的任何内容。你能证实吗? 如果我是对的,你可以通过把它改成“MAXCase…”来摆脱昂贵的“DISTINCT”


你能跟我说一下吗:

我们看到过这样的情况:将原始表转换成另一个表,根据你的主要条件分布,然后查询该表,这样更便宜。

我们看到过这样的情况:将原始表转换成另一个表,根据你的主要条件分布,这样更便宜,然后改为查询该表。

这实际上比我的查询花费更多的时间。在使用内部查询的示例查询中,我的版本需要84秒才能完成,这需要298秒。我不完全理解为什么,但我现在正在使用CTAS开发一个版本。使用SELECT tab_代码可以获得与内部查询相同的性能吗?我现在已经对这个问题进行了相当多的修改。内部查询的执行速度也比较慢,但没有超时一次。以前,我的查询将超时4次中的3次。我对SQL不太熟悉,无法解释为什么它需要更多的时间,但是查询每个会话返回约10万行,可能返回这么多行需要更多的时间,因为我没有要求SQL聚合结果?这实际上比我的查询需要更多的时间。在使用内部查询的示例查询中,我的版本需要84秒才能完成,这需要298秒。我不完全理解为什么,但我现在正在使用CTAS开发一个版本。使用SELECT tab_代码可以获得与内部查询相同的性能吗?我现在已经对这个问题进行了相当多的修改。内部查询的执行速度也比较慢,但没有超时一次。以前,我的查询将超时4次中的3次。我对SQL不太熟悉,无法解释为什么它需要花费更多的时间,但是查询在每个会话中返回大约1000万行,也许返回这么多行需要更多的时间,因为我没有要求SQL聚合结果?
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