【问题标题】:Optimizing SELECT count(*) on large table优化大表上的 SELECT count(*)
【发布时间】:2021-12-21 18:43:05
【问题描述】:

PostgreSQL 14 上具有 64GB 内存和 20 个线程的大型表的基本计数。存储是 NVME 磁盘。

问题:

  • 如何改进此选择计数查询的查询?我应该对 Postgres 配置进行哪些优化?
  • 计划的worker是4个,启动的却是0个,这正常吗?
EXPLAIN (ANALYZE, BUFFERS)
SELECT count(*) FROM public.product;
Finalize Aggregate  (cost=2691545.69..2691545.70 rows=1 width=8) (actual time=330901.439..330902.951 rows=1 loops=1)
  Buffers: shared hit=1963080 read=1140455 dirtied=1908 written=111146
  I/O Timings: read=36692.273 write=6548.923
  ->  Gather  (cost=2691545.27..2691545.68 rows=4 width=8) (actual time=330901.342..330902.861 rows=1 loops=1)
        Workers Planned: 4
        Workers Launched: 0
        Buffers: shared hit=1963080 read=1140455 dirtied=1908 written=111146
        I/O Timings: read=36692.273 write=6548.923
        ->  Partial Aggregate  (cost=2690545.27..2690545.28 rows=1 width=8) (actual time=330898.747..330898.757 rows=1 loops=1)
              Buffers: shared hit=1963080 read=1140455 dirtied=1908 written=111146
              I/O Timings: read=36692.273 write=6548.923
              ->  Parallel Index Only Scan using points on products  (cost=0.57..2634234.99 rows=22524114 width=0) (actual time=0.361..222958.361 rows=90993600 loops=1)
                    Heap Fetches: 46261956
                    Buffers: shared hit=1963080 read=1140455 dirtied=1908 written=111146
                    I/O Timings: read=36692.273 write=6548.923
Planning:
  Buffers: shared hit=39 read=8
  I/O Timings: read=0.398
Planning Time: 2.561 ms
JIT:
  Functions: 4
  Options: Inlining true, Optimization true, Expressions true, Deforming true
  Timing: Generation 0.691 ms, Inlining 104.789 ms, Optimization 24.169 ms, Emission 22.457 ms, Total 152.107 ms
Execution Time: 330999.777 ms

【问题讨论】:

    标签: sql database postgresql postgresql-performance postgresql-parallel-query


    【解决方案1】:

    计划的worker是4个,启动的却是0个,正常吗?

    当太多并发事务竞争有限数量的允许并行工作时,可能会发生这种情况。 The manual:

    计划者将考虑使用的后台工作人员的数量 最多限制为max_parallel_workers_per_gather。这 任何时候可以存在的后台工作人员总数为 受max_worker_processes 和 max_parallel_workers。因此,有可能为 并行查询以比计划更少的工作人员运行,甚至没有 工人。最佳计划可能取决于工人的数量 可用,因此这可能会导致查询性能不佳。如果 这种情况经常发生,考虑增加 max_worker_processes 和 max_parallel_workers 让更多的工人 可以同时运行或交替运行 max_parallel_workers_per_gather 让规划者要求更少 工人。

    您还可以优化整体性能以释放资源,或获得更好的硬件(除了提升max_parallel_workers)。

    还有什么问题:

    堆取数:46261956

    对于 90993600 行。这对舒适来说太多了。仅索引扫描不应该执行那么多堆提取。

    这两种症状都表明大量并发写入访问(或长时间运行的事务占用资源并阻止 autovacuum 完成其工作)。调查这一点,和/或调整每个表 autovacuum 表 product 的设置,使其更具侵略性,以便列统计信息更有效并且可见性地图可以跟上。见:

    此外,如果表统计信息有效,那么(快得惊人!)估计可能就足够了?见:

    【讨论】:

    • @CodeGuru:还要注意关于估计的附加部分。
    猜你喜欢
    • 2016-07-27
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 2011-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-21
    相关资源
    最近更新 更多