早于 10 的 PostgreSQL 版本在单个后端执行每个查询,该后端是具有单个线程的进程。它不能使用多个 CPU 进行查询。它在单个查询中可以实现的 I/O 并发性也有所限制,实际上只为位图索引扫描执行并发 I/O,否则依赖操作系统和磁盘系统进行并发 I/O。
PostgreSQL 10+ 支持并行查询。在撰写本文时(PostgreSQL 12 版本)并行查询仅用于只读查询。并行查询支持为某些类型的查询提供了相当多的并行性。
Pg 擅长并发负载许多较小的查询,并且很容易以这种方式使您的系统饱和。它只是不擅长为一两个非常大的查询充分利用系统资源,尽管随着为更多类型的查询添加并行查询支持,这种情况正在改善。
如果您使用的是没有并行查询的旧 PostgreSQL,或者您的查询尚未受益于并行查询支持:
你能做的就是把工作分成几块,然后交给工人。你已经提到了这一点:
我可以修改查询以使 postgre 使用所有可用的 CPU 同时并行计算不同行的 GetStatistic 吗?
有多种工具,如DBlink、PL/Proxy、pgbouncer和PgPool-II旨在帮助完成此类工作。或者,您可以自己做,启动(比如说)8 个工作人员,每个工作人员都连接到数据库并UPDATE ... WHERE id BETWEEN ? AND ?
使用不重叠的 ID 范围执行语句。一个更复杂的选择是让队列控制器向工作人员分发大约 1000 个 ID 的UPDATE
范围,然后该范围要求新的 ID。
请注意,64 个 CPU 并不意味着 64 个并发工作人员是理想的。在写入方面,您的磁盘 I/O 也是一个因素。如果您将UPDATE
事务设置为使用 acommit_delay
并且(如果对您的业务对此数据的要求安全),您可以减少 I/O 成本,synchronous_commit = 'off'
那么同步的负载应该会显着减少。尽管如此,最好的吞吐量很可能远低于 64 个并发工作人员。
GetStatistic
通过将函数转换为可内联的 SQL 函数或视图,而不是目前可能是循环繁重的过程 PL/pgSQL 函数,您的函数很可能会变得更快。如果您显示此功能可能会有所帮助。