使用 Postgres 进行行缓存
row caching with Postgres
作为 Postgres 的新手,我有一个关于缓存的问题。我不知道数据库处理了多少,我自己需要处理多少。
我有一些行是时间序列的一部分。举个例子,假设我每秒有 1 行。
我的查询是滚动获取最后一分钟(60 行)(从现在 - 1 分钟到现在)。
理想情况下,我可以在客户端缓存最后的结果并请求最后一秒。
不幸的是,数据中有漏洞:一些行丢失了,几秒钟后我被添加了。所以无论如何我都需要查询整个事情。
我可以找到漏洞的位置并针对这些进行查询,这也是一种选择。
我想知道的是:Postgres 自己执行了多少缓存?
如果我有一个查询返回第 3、4、5、6 行和我的下一个查询 returns 4、5、6、7。是否必须再次获取第 4、5、6 行,或者它们被数据库缓存了吗?
PostgreSQL 自动缓存数据。数据以8kB为单位读取、写入和缓存,每当访问一行时,都会缓存包含该行的块。
所有你需要确保的是你在你的 table 的时间戳上有一个索引,否则 PostgreSQL 必须读取整个 table 来计算结果。使用索引,它将只读取(和缓存)包含您需要的数据的块,这将加快您对这些数据的下一次查询。
Postgres 包含一个广泛的缓存系统。同一查询的后续执行很可能会使用缓存数据,但我们实际上对其没有影响,因为缓存是自主工作的。可以而且应该做的是使用准备好的语句。每 the documentation:
A prepared statement is a server-side object that can be used to optimize performance. When the PREPARE statement is executed, the specified statement is parsed, analyzed, and rewritten. When an EXECUTE command is subsequently issued, the prepared statement is planned and executed. This division of labor avoids repetitive parse analysis work, while allowing the execution plan to depend on the specific parameter values supplied.
但是,问题中描述的场景提出了一种完全不同的方法来解决这个问题,即使用 NOTIFY / LISTEN
功能。简而言之:
- 每次向 table、
中插入一行时,服务器都会发送一个通知
- 应用程序在约定的频道上侦听并接收新输入的行。
在此解决方案中,应用程序仅执行一次查询并完成来自通知的数据。
触发函数示例:
create or replace function before_insert_on_my_table()
returns trigger language plpgsql as $$
begin
perform pg_notify('my_data', new::text);
return new;
end $$;
create trigger before_insert_on_my_table
before insert on my_table
for each row execute procedure before_insert_on_my_table();
LISTEN
语句在应用程序中的实现取决于所使用的语言。例如,python psycopg2 有 convenient tools for it.
在文档中阅读有关 NOTIFY 的更多信息。
作为 Postgres 的新手,我有一个关于缓存的问题。我不知道数据库处理了多少,我自己需要处理多少。
我有一些行是时间序列的一部分。举个例子,假设我每秒有 1 行。
我的查询是滚动获取最后一分钟(60 行)(从现在 - 1 分钟到现在)。
理想情况下,我可以在客户端缓存最后的结果并请求最后一秒。 不幸的是,数据中有漏洞:一些行丢失了,几秒钟后我被添加了。所以无论如何我都需要查询整个事情。
我可以找到漏洞的位置并针对这些进行查询,这也是一种选择。
我想知道的是:Postgres 自己执行了多少缓存?
如果我有一个查询返回第 3、4、5、6 行和我的下一个查询 returns 4、5、6、7。是否必须再次获取第 4、5、6 行,或者它们被数据库缓存了吗?
PostgreSQL 自动缓存数据。数据以8kB为单位读取、写入和缓存,每当访问一行时,都会缓存包含该行的块。
所有你需要确保的是你在你的 table 的时间戳上有一个索引,否则 PostgreSQL 必须读取整个 table 来计算结果。使用索引,它将只读取(和缓存)包含您需要的数据的块,这将加快您对这些数据的下一次查询。
Postgres 包含一个广泛的缓存系统。同一查询的后续执行很可能会使用缓存数据,但我们实际上对其没有影响,因为缓存是自主工作的。可以而且应该做的是使用准备好的语句。每 the documentation:
A prepared statement is a server-side object that can be used to optimize performance. When the PREPARE statement is executed, the specified statement is parsed, analyzed, and rewritten. When an EXECUTE command is subsequently issued, the prepared statement is planned and executed. This division of labor avoids repetitive parse analysis work, while allowing the execution plan to depend on the specific parameter values supplied.
但是,问题中描述的场景提出了一种完全不同的方法来解决这个问题,即使用 NOTIFY / LISTEN
功能。简而言之:
- 每次向 table、 中插入一行时,服务器都会发送一个通知
- 应用程序在约定的频道上侦听并接收新输入的行。
在此解决方案中,应用程序仅执行一次查询并完成来自通知的数据。
触发函数示例:
create or replace function before_insert_on_my_table()
returns trigger language plpgsql as $$
begin
perform pg_notify('my_data', new::text);
return new;
end $$;
create trigger before_insert_on_my_table
before insert on my_table
for each row execute procedure before_insert_on_my_table();
LISTEN
语句在应用程序中的实现取决于所使用的语言。例如,python psycopg2 有 convenient tools for it.
在文档中阅读有关 NOTIFY 的更多信息。