时间过滤器
时间过滤器(Temporal fliter)允许您基于时间间隔过滤数据,通常用于检索特定时间范围内的数据。有了它,您就可以基于特定时间过滤数据,如当前时间、特定日期或日期范围。通过使用时间过滤器,您可以确保您的查询只返回您感兴趣的时期的相关数据,使您的数据分析更加准确和高效。
句法
一个有效的时间过滤器包括以下组成部分:
- 比较运算符,包括
<
、>
、<=
、>=
、=
和BETWEEN
- 以涉及基 Relation 中列的时间表达式作为左侧
- 以
NOW() +/- interval
作为右侧的时间表达式
时间过滤器条件不能使用 OR
运算符与另一个时间过滤器连接,但可以与普通表达式连接。请参见下面的例子:
-- 允许
t > NOW() - INTERVAL '1 hour' OR t IS NULL OR a < 1
-- 无效
t > NOW() - INTERVAL '1 hour' OR t < NOW() - INTERVAL '1 hour'
-- 无效
(a < 1) OR (t > NOW() - INTERVAL '1 hour' AND t < NOW() - INTERVAL '1')
此外,时间过滤器条件不能使用 AND
运算符与包含时间过滤器的表达式连接。例子如下:
-- 无效
(t > NOW() - INTERVAL '1 hour' OR t is NULL OR a < 1)
AND (t < NOW() - INTERVAL '1 hour' OR a < 1)
用法 1:删除和清理过期数据
当 NOW()
与时间表达式作为基 Relation 的下界条件时,如 t > NOW() - INTERVAL '1 hour'
,它可以过滤掉事件时间太旧的记录。
以下查询返回 sales
表过去一周内的所有销售记录。
SELECT *
FROM sales
WHERE sale_date > NOW() - INTERVAL '1 week';
此查询中的时间过滤器是 sale_date > NOW() - INTERVAL '1 week'
。它基于 sale_date
列过滤行,并检查它是否在当前时间的一周内,或 NOW()
的一周内。
以下查询返回 user_sessions
表中, 将last_active
时间戳加上两倍session_timeout
后,其和大于当前时间戳的所有行,这些数据属于会话处于活动状态的用户。此查询可用于从数据库中清理旧的用户会话,删除不再满足条件的任何行。
SELECT *
FROM user_sessions
WHERE last_active + session_timeout * 2 > NOW();
此查询中的时间过滤器位于 WHERE
子句中。它检查最后活动的时间戳加上两倍会话超时是否大于当前时间或 NOW()
。这表明会话仍处于活动状态。
用法 2:延迟表变更
当 NOW()
与时间表达式作为基 Relation 的上界条件时,如 ts + interval '1 hour' < now()
,它可以“延迟”输入了 Relation 的表变更。当与时间 Join一起使用时,这可能很有用。
以下一个使用时间 Join 扩展表的典型例子。
CREATE SOURCE fact(id1 INT, a1 INT, p_time TIMESTAMPTZ AS proctime()) WITH (connector = 'kafka', ...);
CREATE TABLE dimension(id2 INT, a2 INT, PRIMARY KEY (id2)) WITH (connector = 'jdbc', ...);
CREATE MATERIALIZED VIEW mv AS SELECT id1, a1, a2 FROM fact LEFT JOIN dimension FOR SYSTEM_TIME AS OF PROCTIME() ON id1 = id2;
然而,在上述例子中,由于网络或其他阶段的延迟,我们并不能保证 fact
的记录到达时,dimension
表中相应的记录已经到达。于是,我们可以在 fact
源上设置时间过滤器以引入延迟并等待维度表的变更。
CREATE MATERIALIZED VIEW mv AS
SELECT
id1, a1, a2
FROM (
-- 将源延迟 5 秒
SELECT * FROM fact WHERE fact.p_time + INTERVAL '5' SECOND < NOW()
) fact
LEFT JOIN dimension FOR SYSTEM_TIME AS OF PROCTIME() ON id1 = id2;
当前,RisingWave 的优化器不能确保时间过滤器能条件下推。请像 SQL 示例中那样,将时间过滤器作为一个子查询添加到 FROM
子句中,而不是将时间过滤器写在查询的顶层 WHERE
子句中。
示例中的 PROCTIME
可以替换为记录中的事件时间。