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

相关推荐
THMAIL2 小时前
量化股票从贫穷到财务自由之路 - 零基础搭建Python量化环境:Anaconda、Jupyter实战指南
linux·人工智能·python·深度学习·机器学习·金融
逍遥浪子~3 小时前
docker实践(一)
运维·docker·容器
让子弹飞023 小时前
36.2Linux单总线驱动DS18B20实验(详细讲解代码)_csdn
linux·ubuntu·驱动的分离和分层
ChinaRainbowSea3 小时前
7. LangChain4j + 记忆缓存详细说明
java·数据库·redis·后端·缓存·langchain·ai编程
Yana.nice3 小时前
yum list 和 repoquery的区别
linux
AI云原生3 小时前
如何使用Docker快速运行Firefox并实现远程访问本地火狐浏览器的教程
运维·docker·云原生·容器·serverless·firefox·kubeless
今生相伴9913 小时前
ELFK:企业级日志管理的完整解决方案——从入门到精通
运维·elk·elasticsearch
码出钞能力4 小时前
更换libc.so导致linux变砖,通过LD_PRELOAD挽救
linux·服务器
小马学嵌入式~4 小时前
嵌入式 SQLite 数据库开发笔记
linux·c语言·数据库·笔记·sql·学习·sqlite