Where 子句不适用于 ClickHouse 视图

Posted

技术标签:

【中文标题】Where 子句不适用于 ClickHouse 视图【英文标题】:Where clause not working with the ClickHouse view 【发布时间】:2020-02-28 07:13:34 【问题描述】:

我正在尝试在源表上创建视图,然后从视图中选择特定时间戳范围的数据并将其放入目标表中。

我们有一个源表:

100 万行被推送到对应于 1 月 1 日至 1 月 31 日数据的源表。

    CREATE TABLE IF NOT EXISTS source(
      CELL          String,
      TIMESTAMP     DateTime,
      COUNTER1      Float32,
      COUNTER2      Float32,
      COUNTER3      Float32,
      COUNTER4      Float32,
      COUNTER5      Float32,
      COUNTER6      Float32,
      InsertionTime DateTime DEFAULT now(),      /* Insertion Time */
      QHour         DateTime DEFAULT toStartOfFifteenMinutes(TIMESTAMP)
    ) ENGINE=ReplacingMergeTree()
    PARTITION BY toYYYYMM(TIMESTAMP)
    ORDER BY (QHour, TIMESTAMP, CELL)
    SETTINGS index_granularity = 31768

现在,我们在源表上创建了一个视图。

    CREATE VIEW IF NOT EXISTS myView
      AS SELECT
        CELL,
        QHour,
        toStartOfFifteenMinutes(TIMESTAMP)      AS ViewQHour,
        100 * sum(COUNTER1) / sum(COUNTER2)     AS KPI1
      FROM ( 
        SELECT
            CELL,
            TIMESTAMP,
            any(QHour) as QHour
            argMax(COUNTER1, InsertionTime)     AS COUNTER1,
            argMax(COUNTER2, InsertionTime)     AS COUNTER2
        FROM ThreeGCell
        GROUP BY TIMESTAMP, CELL, QHour)
    GROUP BY ViewQHour, CELL
    ORDER BY ViewQHour, CELL

现在,在视图中,我需要从视图中选择一个时间段的数据:1 月 1 日至 1 月 10 日。

SELECT * 
FROM myView 
WHERE QHour >= toDateTime('2020-01-01 00:00:00') AND QHour <= toDateTime('2020-01-10 00:00:00')

但是视图上的选择查询将所有 100 万行添加到目标表中,这是整个 1 月的数据,而我正在寻找特定时期的数据,仅 1 月 1 日至 1 月 10 日。

我有以下问题:

    我们可以修改视图上的查询以仅处理特定时间段吗? 我们能否动态生成推送到源表中的最新数据集的视图? 我的意思是我们只有源表中的过滤数据集并在视图中使用过滤后的数据? 可以修改此类过滤器以使用不同的时间范围吗? 例如,我们在视图中有从 1 月 1 日到 1 月 10 日的数据。 然后在第二次运行中,我们的视图中有 1 月 11 日至 1 月 20 日的数据。

【问题讨论】:

尝试将enable_optimize_predicate_expression-param 应用于如下视图:CREATE VIEW .. ORDER BY .. SETTINGS enable_optimize_predicate_expression = 1 @vladimir :我执行了您建议的更改。但是视图仍然有 100 万行。当我对视图执行选择时,选择仍在处理 100 万行。结果是正确的。但是我正在寻找它来根据选择查询中的时间戳过滤器仅处理视图中有限数量的行。 【参考方案1】:
CREATE VIEW IF NOT EXISTS myView
....
ORDER BY ViewQHour, CELL

大多数数据库禁止使用ORDER BY 创建视图,不幸的是 CH 没有。在最初的设计中允许创建这样的视图是一个错误。

ORDER BY 取消谓词下推,因为它在某些情况下会破坏结果(优化器仍然很弱并且不理解 runningDiff() 和 neighbour() 的情况。

https://github.com/ClickHouse/ClickHouse/issues/9425#issuecomment-592658368

【讨论】:

以上是关于Where 子句不适用于 ClickHouse 视图的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 函数不适用于 WHERE 子句

WHERE 子句中的优化似乎不适用于 UNION

Oracle where exists 子句不适用于 SQL Plus

二级缓存 EF codeFirst 和 Predicate 不适用于 where 子句

Have/Where 子句不适用于使用 Microsoft SQL 的 Haversine 公式

如何在 where 子句上基于 SqlCommand 或 SqlDataAdapter 填充 datagridview? SqlDataAdapter 不适用于哪里?