如果我连接的列具有不同的数据类型,如何将两个表连接在一起?

问题描述 投票:0回答:1

我对 SQL 和 ClickHouse 尤其是新手。我正在尝试根据客户 ID 连接 2 个表。问题是我要连接的两个表中的数据类型不同。我加入的左表列的数据是字符串类型,右表是 int64 或 Nullable。当我尝试将左表的客户 ID 的字符串类型转换为 int64 时,出现超时错误。看来服务器无法解析这么多数据(尽管我通过指定日期范围来限制数据)

这是我导致超时的查询:

WITH
    t AS (
    SELECT ticketId, 
        toInt64(accId) AS accountId,
        datetimeCreated,
        os
    FROM(
        SELECT
            ticketId, 
            accId AS accountId,
            tsToDateTime(entryCreateTime) AS datetimeCreated, 
-- tsToDateTime is a custom function that parses timestamp into the date and time that human beings are used to
            os
        FROM myTab.table 
        PREWHERE 
            datetimeCreated BETWEEN toDateTime(today()) - INTERVAL 5 MONTH AND datetimeCreated AND 
            status = 'new' AND 
            role = 'end-user' AND
            project = 'pj' AND 
            replaceRegexpAll(accountId,'\\D', '') = accountId --need this line to exclude rubbish ids that have anything but digits
        GROUP BY 
            ticketId, 
            accId,
            datetimeCreated,
            os
)
        ),
    p AS (
    SELECT 
        tsToDateTime(ts) AS datetimePaid, accId,
        amount
    FROM otherTab.tab2  
    PREWHERE 
        datetimePaid >= today() - 365
    )
SELECT ticketId, acctId, datetimeCreated,
COUNT(amount) AS payms_cnt,
ROUND(SUM(amount)) AS payms_sum
FROM (
    SELECT 
        t.ticketId, 
        t.accId, 
        t.datetimeCreated,
        t.platform,
        p.datetimePaid,
        p.amount
FROM t
INNER JOIN p ON t.accId = p.accId
WHERE p.datetimePaid BETWEEN t.datetimeCreated - INTERVAL 4 MONTH AND t.datetimeCreated)
GROUP BY accId, ticketId, datetimeCreated, platform
ORDER BY accId, datetimeCreated 
;

我想我还应该提到,考虑到日期范围过滤器,我要加入的表大约有几万行。

我尝试将 accId 从右表(p 表)转换为字符串,但结果是相同的(超时)。我分别检查了这两个表(p 和 t),它们工作正常,直到我尝试加入它们。 我也尝试过

FROM t
INNER JOIN p ON CAST(t.accId AS int) = p.accId

但仍然收到超时。

sql query-optimization clickhouse
1个回答
0
投票

过滤后您的数据会小吗

PREWHERE datetimePaid >= today() - 365
WHERE p.datetimePaid BETWEEN t.datetimeCreated - INTERVAL 4 MONTH AND t.datetimeCreated
?后者无法通过连接下推,因为它取决于两个表中的值,因此它在连接之后执行。

在这种情况下,瓶颈是

p
的大小。您可以使用
EXPLAIN PLAN actions = 1
检查哪个过滤器被按下。从下到上阅读并查找
Prewhere filter column
Filter column
以查看在连接之前执行了哪些过滤器。

此外,如果

t
小于
p
,我可以建议重写查询以在右侧拥有较小的表,但它不会自动完成。

您提到了超时——这是客户端超时吗?对于大型连接,ClickHouse 通常会返回

MEMORY_LIMIT_EXCEPTION
,因为它将正确的表加载到内存中。

您可以考虑使用不同的连接算法,可以将一些数据保存到磁盘,尽管它更多的是缓解内存问题:https://clickhouse.com/blog/clickhouse-filled-supports-joins-how-to -选择正确的算法第5部分

© www.soinside.com 2019 - 2024. All rights reserved.