【发布时间】:2016-01-10 13:23:41
【问题描述】:
我目前正在开展一个项目,该项目涉及使用我的数据库(PostgreSQL 作为 RDMS)跟踪用户及其操作,并且在尝试对每个用户的出现执行 COUNT(*) 时遇到了问题。我想要的是能够有效地计算每个用户从每个记录中出现的次数,并且还能够实现查看特定日期范围。
所以,问题是我们如何计算用户从表格内容中出现的总次数,以及我们如何计算一个日期范围内的总数。
我的尝试
您可能知道,Postgres 不能很好地支持使用索引的 COUNT(*),因此我们必须考虑其他方法来减少它查看的记录数以加快查询速度。所以我的第一种方法是创建一个表来跟踪用户有多少次与他们关联的日志消息,以及在哪一天(类似于物化视图背后的想法,但我不想不断刷新物化视图与我的计数查询)。这是我想出的:
CREATE TABLE users_counts(user varchar(65536), counter int default 0, day date);
CREATE RULE inc_user_date_count
AS ON INSERT TO main_table
DO ALSO UPDATE users_counts SET counter = counter + 1
WHERE user = NEW.user AND day = DATE(NEW.date_);
每次在我的“main_table”中插入新记录时,我们都会更新当前 users_counts 表以增加日期等于新记录日期且用户名相同的记录。
p>注意:“main_table”中的 date_ 列是时间戳,因此我必须将新记录 date_ 转换为 DATE 类型。
问题是,如果当日我的新表“users_count”中不存在用户列值,那么什么都不会更新。
这是我的问题:
如何编写规则,以便我们检查用户在当天是否存在,如果存在则增加该计数器,否则插入用户、日期和计数器为 1 的新行;
我也想知道我的方法是否有意义,或者是否有任何我没有想到的想法。随着数据库的增长,执行计数的效率越来越低,因此我想避免任何性能瓶颈。
编辑 1:我实际上可以通过创建单独的规则来解决这个问题,但我不确定这是否正确:
CREATE RULE test_insert AS ON INSERT TO main_table
DO ALSO INSERT INTO users_counts(user, counter, day)
SELECT NEW.user, 1, DATE(NEW.date)
WHERE NOT EXISTS (SELECT user FROM users.log_messages WHERE user = NEW.user_);
基本上,如果用户在我的名为 user_counts 的 CACHED 表中尚不存在,则会发生插入,并且上面的第一条规则会更新计数。
我不确定的是我如何知道首先调用哪个规则,更新规则或插入..并且必须有更好的方法,我如何结合这两个规则?这可以用函数来完成吗?
【问题讨论】:
标签: postgresql count