PG案例系列1:优化大表的count(*)

news2024/11/25 11:01:46

文章目录

  • 一. 问题描述
  • 二. 解决方案
    • 2.1 收集统计信息
    • 2.2 并行
    • 2.3 autovacuum
    • 2.3 统计信息读取
  • 参考:

一. 问题描述

前端页面需要分页展示,经常需要查询总数,然后做分页展示。

遇到的问题是,第一次执行会很慢,6秒左右,如果间隔时间段第二次执行,因为缓存了第一次的数据,所以查询很快。

表的总行数才56W左右,而且有主键索引

表总数据量21GB
主键索引数据量390M
最小的索引数据量52M

image.png

image.png

二. 解决方案

领导是做开发出身的,习惯的是redis、Elastic、StarRocks、ClickHouse之类的数据库,这类数据库的count() 都是非常快的,完全理解不了,为什么一个几十万的count() 查询需要 六七秒,甚至更久。

首先想到的是网上看一看,原来有好多大佬已经遇到过类似的问题了。
image.png

2.1 收集统计信息

analy tablename;

统计信息收集速度还比较快,大概3秒钟左右。然而收集完成后,问题依旧。

2.2 并行

count(*) 操作较为简单,既然资源足够,完全可以开更多的并行来协助解决这个问题。

show max_parallel_workers;
show max_parallel_workers_per_gather ;

原来默认已经开了2个并行了

set max_parallel_workers=10
set max_parallel_workers_per_gather=10;
alter table table_name set (parallel_workers =4);
alter table table_name set (parallel_workers =6);
select pg_sleep(300);

将并行度调整为4和6,分别看看执行情况。

因为数据量不大,并行度为4的运行速度在2秒左右,并行度为6的运行速度在10秒左右。

顾此处考虑将并行度调整为4

2.3 autovacuum

对于count(*) 操作,完全可以借助索引,因为索引占的空间比表小太多,那么几十M的索引扫描起来为什么那么慢呢?

尝试扫描一个小的索引而不是整个表来计算行数是很好的一个解决方案。然而,由于PostgreSQL的多版本并发控制策略,这并不是那么简单。每个行版本(“元组”)均包含可见的数据库快照的信息。但是,此信息未(冗余地)存储在索引中。因此,通常不足以对索引中的条目进行计数,因为PostgreSQL必须访问表条目(“堆元组”)以确保索引条目可见。为了缓解这个问题,PostgreSQL引入了可见性映射(visibility map),这是一种数据结构,用于存储每个人是否都可以看到表块中的所有元组。如果大多数表块都是可见的,则索引扫描不需要经常访问堆元组来确定可见性。这样的索引扫描称为“仅索引扫描”,因此会更快地扫描索引以对行进行计数。现在是VACUUM维护了可见性映射,所以如果你想使用索引来加速count(*),请确保autovacuum在表上运行得足够频繁。

 psql -h hostname -U dbname 
\timing
ALTER TABLE table_name SET (
   autovacuum_vacuum_scale_factor = 0,
   autovacuum_analyze_scale_factor = 0,
   autovacuum_vacuum_threshold = 1000,
   autovacuum_analyze_threshold = 1000);

select count(*) from table_name;
select pg_sleep(300);
select count(*) from table_name;
select pg_sleep(300);
select count(*) from table_name;
select pg_sleep(300);
select count(*) from table_name;
select pg_sleep(300);
select count(*) from table_name;

开启4个并行,并调整参数后,我进行了5次测试,以示公平,每次测试后,休眠5分钟
从结果可以看,执行的时间在1秒左右

2.3 统计信息读取

如果要求不那么准确,可以直接从统计信息中读取

SELECT reltuples::bigint
  FROM pg_catalog.pg_class
 WHERE relname = 'mytable';

我测试了下,未收集统计信息之前,表行数不准,大概是2倍的差距。
手工收集了统计信息之后,也存在一定的差距。

目前1秒钟可以出结果,没必要冒这个风险了。

参考:

  1. https://www.modb.pro/db/617661
  2. https://dba.stackexchange.com/questions/245990/postgresql-extremely-slow-count-with-index-simple-query

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/587848.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++数据结构:二叉树之一(数组存储)

文章目录 前言一、二叉树的基本定义二、二叉树的基本性质三、二叉树的存储(数组)总结原创文章,未经许可,禁止转载 前言 树是一种非线性数据结构,它由若干个节点和边组成。每个节点都有一个值,而边则表示节…

2核4G5M性能测评:腾讯云轻量应用服务器CPU内存带宽系统盘

腾讯云轻量应用服务器2核4G5M配置一年168元,三年628元,100%CPU性能,5M带宽下载速度640KB/秒,60GB SSD系统盘,月流量500GB,折合每天16.6GB流量,超出月流量包的流量按照0.8元每GB的支付流量费&…

SuperMap iDesktopX扩展开发之GP算子扩展

作者:dongyx SuperMap iDesktopX是超图研究院推出的一款跨平台的桌面GIS软件,兼容Windows和Linux,同时iDesktopX也采用的是插件式扩展开发框架,支持定制开发。 使用iDesktopX定制开发有以下优势: ⚫ 采用 Swing 图形界…

第五十八天学习记录:C语言进阶:文件操作1

什么是文件 在程序设计中,一般有两种文件:程序文件、数据文件 程序文件 包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.e…

TM7707 评估前做的功课

目录 硬件 模拟输入范围 转换速度与有效位数 数字电平匹配 建立时间 基准电压 软件 寄存器 硬件 MCU 3.3V 平台; ADC mclk 2.4576mhz 模拟输入范围 在非缓冲模式下,共模输入范围是从 GND 到 V DD 。模拟输入电压的绝对值处在 GND-30mV 和 …

SAP不停机做client copy ,把800数据覆盖到600,导致在600很多单据创建不出来

不停机做client copy ,把800数据覆盖到600,但是因为没有停机,导致在800还在产生单据,以至于600的 number range 不对,很多单据都能保存成功但是查寻不到 涉及到的单据(包括但不限于) 采购订单 生…

GPT-4 太贵?试试这 6 个免费且优秀的替代方案

大家好,我是可夫小子,《小白玩转ChatGPT》专栏作者,关注AIGC、读书和自媒体。 目录 AutoGPT - 直接从您的浏览器使用 Bard - Google AI 的免费工具。 Bing - New Bing 已经支持GPT-4, Claude - Anthropic对标ChatGPT Hugging…

适合每个人的热门CSS工具

本文首发于微信公众号:大迁世界, 我的微信:qq449245884,我会第一时间和你分享前端行业趋势,学习途径等等。 更多开源作品请看 GitHub https://github.com/qq449245884/xiaozhi ,包含一线大厂面试完整考点、资料以及我的…

Jenkins+Gogs自动远程Docker环境部署django项目

1.Jenkins安装或确认必要插件 jenkins安装或确认必要插件gitlab、Publish Over SSH。 Dashboard--Manage Jenkins--Plugin Manager 2.Publish Over SSH配置 jenkins配置SSH连接django服务部署的对象服务器 Dashboard--Manage Jenkins--Configure System,找到 Publ…

LIS和LIMS有什么区别?

术语“实验室信息系统”(LIS)和“实验室信息管理系统”(LIMS)经常会引起混淆,并且倾向于互换使用这些术语。通常,术语“ LIS”是指用于管理医院或医疗环境中的临床诊断测试的系统。另一方面,LIM…

基于C#的串口扫描枪通信实战

今天搞大事,观众们动起来,搞事的目的是 掌握串口通信及winform开发技术 硬件设备:1、串口激光扫描枪,注意是串口,不是USB口 2、USB转串口的连接线一根,如图连接所示 3、USB扩展器一个,如果你电…

图片优化: CssSprites与Base64编码

文章目录 1 css sprites1.1 CSS Sprites是什么1.2 为什么需要css sprites1.3 优势1.4 使用原理 2 图片Base64编码 1 css sprites 1.1 CSS Sprites是什么 CSS Sprites是一种网页图片应用处理方式。 又被解释为: CSS精灵CSS图像拼合CSS贴图定位CSS图片精灵CSS雪碧图…

快六一啦,学习CSS3实现一个冰淇淋动画特效

快六一啦,小时候顶多吃个小冰棍,或者是那种小冰袋,现在的小朋友真是好,动不动就能吃到冰淇淋,今天用CSS3实现一个冰淇淋的动画特效吧 目录 实现思路 桶身的实现 冰淇淋身体的实现 五彩颗粒的实现 HTML源码 CSS3源…

17 张程序员专属壁纸推荐

1、三思后再写代码!!! 2、从世界上搜索喜欢你的人!!! 3、代码没写完,哪里有脸睡觉!!! 4、程序员的 Home 键!!! 5、编程是…

【完整项目开发】Springboot+vue教学材料管理系统定制开发

Springbootvue 的专业建建设材料管理系统。 **大家好,今天分享最近做的一套系统。**起因源于小伙伴的需求 文末有的获取方式,如需定制系统,需求发来,我为你分忧,搞起 一、 项目介绍 基于各个专业,对教…

代码随想录算法训练营day56 | 583. 两个字符串的删除操作,72. 编辑距离,编辑距离总结篇

代码随想录算法训练营day56 | 583. 两个字符串的删除操作,72. 编辑距离,编辑距离总结篇 583. 两个字符串的删除操作解法一:动态规划解法二:计算最长公共子序列,然后用数组长度减掉子序列长度 72. 编辑距离解法一&#…

界面组件DevExpress ASP.NET Core v22.2 - UI组件升级

DevExpress ASP.NET Core Controls使用强大的混合方法,结合现代企业Web开发工具所期望的所有功能。该套件通过ASP.NET Razor标记和服务器端ASP.NET Core Web API的生产力和简便性,提供客户端JavaScript的性能和灵活性。ThemeBuilder工具和集成的Material…

【操作系统】01.操作系统概论

操作系统的发展历史 未配置操作系统 手工操作阶段 用户独占全机,人机速度矛盾导致系统资源利用率低 脱机输入输出方式 为了缓解主机cpu和IO设备之间速度不匹配的矛盾,出现了脱机IO技术 在外围机的控制下,通过输入设备,将数据输…

Spring事务和事务的传播机制

一、为什么需要事务 1.1事务定义 将一组操作封装成一个执行单元,要么全部成功要么全部失败。 1.2为什么要用事物 例如转账分为两个操作: 第⼀步操作:A 账户 -100 元。第⼆步操作:B 账户 100 元。 如果没有事务,第…

脱岗监测预警系统 yolov5

脱岗监测预警系统可以通过pythonyolov5网络模型深度学习算法,脱岗监测预警算法对现场人员岗位进行实时监测,自动识别是否存在脱岗行为,并及时发出警报。Yolo意思是You Only Look Once,它并没有真正的去掉候选区域,而是…