我有一个带有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)。我真的很惊讶它一点都有效,但它大部分时间都有效。
有没有更有效的方法来解决这个问题?
答案 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)
如果我正确猜测,X.I_TS实际上是一个'时间戳',因此我希望它每天包含许多不同的值。你能证实吗? 如果我是对的,那么查询可能会从将“由X.I._TS分组,......”更改为“分组1,......”
此外,'Count(Distinct Case ...'永远不会返回除1或NULL之外的任何内容。你能确认一下吗? 如果我是对的,你可以通过将它更改为'MAX(案例......'
你能跟我来吗:)。