PgSQL监控死元组和自动清理状态的SQL语句执行报错ERROR: division by zero原因分析和解决方法

监控死元组和自动清理状态SQL语句,执行后报错,解决方法:

sql 复制代码
报错SQL:
SELECT schemaname, relname, n_live_tup, n_dead_tup,
    (n_dead_tup * 100.0 / (n_live_tup + n_dead_tup)) AS dead_tup_ratio,
    last_autovacuum, last_autoanalyze
 FROM pg_stat_user_tables
 ORDER BY n_dead_tup DESC
 LIMIT 10;

执行后报错如下:

ERROR: division by zero

怎么修改SQL语句?

这个错误是因为有些表的 n_live_tupn_dead_tup 都是零。可以使用以下几种方法修复:

方法1:使用 NULLIF() 函数(推荐)

sql 复制代码
SELECT schemaname, relname,
       n_live_tup, n_dead_tup,
       (n_dead_tup * 100.0 / NULLIF((n_live_tup + n_dead_tup), 0)) AS dead_tup_ratio,
       last_autovacuum, last_autoanalyze
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 10;

方法2:使用 CASE 语句

sql 复制代码
SELECT schemaname, relname,
       n_live_tup, n_dead_tup,
       CASE 
           WHEN (n_live_tup + n_dead_tup) = 0 THEN 0 
           ELSE (n_dead_tup * 100.0 / (n_live_tup + n_dead_tup)) 
       END AS dead_tup_ratio,
       last_autovacuum, last_autoanalyze
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 10;

方法3:使用 COALESCE() 提供默认值

sql 复制代码
SELECT schemaname, relname,
       n_live_tup, n_dead_tup,
       COALESCE((n_dead_tup * 100.0 / NULLIF((n_live_tup + n_dead_tup), 0)), 0) AS dead_tup_ratio,
       last_autovacuum, last_autoanalyze
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 10;

方法4:过滤掉空表(如果业务需要)

sql 复制代码
SELECT schemaname, relname,
       n_live_tup, n_dead_tup,
       (n_dead_tup * 100.0 / (n_live_tup + n_dead_tup)) AS dead_tup_ratio,
       last_autovacuum, last_autoanalyze
FROM pg_stat_user_tables
WHERE (n_live_tup + n_dead_tup) > 0  -- 只处理有数据的表
ORDER BY n_dead_tup DESC
LIMIT 10;

方法5:更完整的解决方案(包含更多信息)

sql 复制代码
SELECT schemaname, relname,
       n_live_tup AS live_tuples,
       n_dead_tup AS dead_tuples,
       (n_live_tup + n_dead_tup) AS total_tuples,
       CASE 
           WHEN (n_live_tup + n_dead_tup) = 0 THEN 0 
           ELSE ROUND((n_dead_tup * 100.0 / (n_live_tup + n_dead_tup))::numeric, 2) 
       END AS dead_tup_ratio_percent,
       pg_size_pretty(pg_total_relation_size(schemaname || '.' || relname)) AS total_size,
       last_autovacuum,
       last_autoanalyze,
       age(now(), COALESCE(last_autovacuum, '1970-01-01'::timestamp)) AS since_last_autovacuum
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 10;

推荐使用的方法1(NULLIF)

这是最简洁和高效的方法,它:

  1. 在除数为零时返回 NULL
  2. 避免了除零错误
  3. 代码简洁易读

执行修改后的查询就不会再出现 "division by zero" 错误了。NULLIF() 函数会在 (n_live_tup + n_dead_tup) 为零时返回 NULL,而任何数除以 NULL 都会返回 NULL,从而避免错误。

相关推荐
Allstar_436 分钟前
全星研发项目管理APQP系统支持本地/私有云,开放API对接ERP/MES/PLM/OA,分级权限、版本追溯、ECN闭环,低代码配置,便于研发质量一体化扩展
运维
这个DBA有点耶13 分钟前
数据库数据同步解决方案怎么选?6款主流工具横向对比与信创选型指南
数据库·架构·dba
嵌入式小能手18 分钟前
飞凌嵌入式ElfBoard-Shell编程应用实例-提取字符并设置rtc时间
linux
刃神太酷啦21 分钟前
Redis 核心进阶:哨兵、集群、缓存问题与分布式锁详解----《Hello Redis!》(6)
linux·c语言·数据库·c++·redis·分布式·缓存
小雷信息医学22 分钟前
不会写复杂代码也能发 SCI?手把手教你用 InSpireR 交互系统一键提取、合并与导出临床科研宽表【第三章】
数据库
大卡片30 分钟前
LCD相关知识
linux
colourmind39 分钟前
K3S+Hami+Higress+Vip(nginx+keepalived)搭建云原生高可用的大模型部署平台
运维·nginx·云原生
闲云野鹤在人间43 分钟前
Docker入门|第3章 镜像详解
linux·网络·docker·容器·centos·云计算·php
小卿噢1 小时前
malloc 成功 ≠ 你有内存:一次把 OOM 从头测到尾
linux·后端
团子股股东峥哥1 小时前
day38-RHEL-管理存储堆栈
linux·运维·服务器