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,从而避免错误。

相关推荐
LCG元12 小时前
深耕多智能体编排,解锁复杂Agent开发之路
前端·数据库·人工智能
宋浮檀s12 小时前
应急响应(系统日志)
linux·运维·网络安全·应急响应
arronKler12 小时前
MySQL命令行导出数据库
c语言·数据库·mysql
老卢聊运维12 小时前
kdc-server部署kerberos认证
大数据·运维·hdfs
新时代农民工~12 小时前
PostgreSQL 主从复制(流复制)实战配置指南:Windows 环境详细步骤
数据库·windows·postgresql
Plastic garden12 小时前
Redis(2) redis的高可用
java·数据库·redis
cui_ruicheng12 小时前
Linux网络编程(七):TCP Socket编程与EchoServer
linux·服务器·网络·tcp/ip
feasibility.12 小时前
nvidia-smi 失灵,显存凭空消失?—— NVML 驱动版本错配的记录
linux·运维·服务器·经验分享·nvidia·驱动
Fleshy数模12 小时前
基于 CSV 数据分析的课堂教学问题诊断与改进建议系统
数据库·人工智能·大模型·llm
ccice0112 小时前
硬核数据技术:驱动Gemini境像站完成从自然语言到SQL查询、数据可视化与洞察报告的全链路自动化(国内镜像免费实测
数据库·oracle