ITPub博客

首页 > 数据库 > 国内数据库 > 表膨胀的查询方法

表膨胀的查询方法

原创 国内数据库 作者:瀚高PG实验室 时间:2022-01-04 16:20:40 0 删除 编辑
文档用途

本文旨在介绍表膨胀的查询方法。

详细信息

可以通过如下sql语句定位膨胀的表。

WITH constants AS(

SELECT

current_setting('block_size')::NUMERIC AS bs,

23 AS hdr,

4 AS ma

),

bloat_info AS(

SELECT

ma,

bs,

schemaname,

tablename,

(

datawidth +(

hdr + ma -(

CASE

WHEN hdr % ma = 0 THEN ma

ELSE hdr % ma

END

)

)

)::NUMERIC AS datahdr,

(

maxfracsum*(

nullhdr + ma -(

CASE

WHEN nullhdr % ma = 0 THEN ma

ELSE nullhdr % ma

END

)

)

) AS nullhdr2

FROM

(

SELECT

schemaname,

tablename,

hdr,

ma,

bs,

SUM(( 1 - null_frac )* avg_width ) AS datawidth,

MAX( null_frac ) AS maxfracsum,

hdr +(

SELECT

1 + COUNT(*)/ 8

FROM

pg_stats s2

WHERE

null_frac <> 0

AND s2.schemaname = s.schemaname

AND s2.tablename = s.tablename

) AS nullhdr

FROM

pg_stats s,

constants

GROUP BY

1,

2,

3,

4,

5

) AS foo

),

table_bloat AS(

SELECT

schemaname,

tablename,

cc.relpages,

bs,

CEIL(

(

cc.reltuples*(

(

datahdr + ma -(

CASE

WHEN datahdr % ma = 0 THEN ma

ELSE datahdr % ma

END

)

)+ nullhdr2 + 4

)

)/(

bs - 20::FLOAT

)

) AS otta

FROM

bloat_info

JOIN pg_class cc ON

cc.relname = bloat_info.tablename

JOIN pg_namespace nn ON

cc.relnamespace = nn.oid

AND nn.nspname = bloat_info.schemaname

AND nn.nspname <> 'information_schema'

),

index_bloat AS(

SELECT

schemaname,

tablename,

bs,

COALESCE(

c2.relname,

'?'

) AS iname,

COALESCE(

c2.reltuples,

0

) AS ituples,

COALESCE(

c2.relpages,

0

) AS ipages,

COALESCE(

CEIL(

(

c2.reltuples*(

datahdr - 12

)

)/(

bs - 20::FLOAT

)

),

0

) AS iotta -- very rough approximation, assumes all cols

FROM

bloat_info

JOIN pg_class cc ON

cc.relname = bloat_info.tablename

JOIN pg_namespace nn ON

cc.relnamespace = nn.oid

AND nn.nspname = bloat_info.schemaname

AND nn.nspname <> 'information_schema'

JOIN pg_index i ON

indrelid = cc.oid

JOIN pg_class c2 ON

c2.oid = i.indexrelid

) SELECT

TYPE,

schemaname,

object_name,

bloat,

pg_size_pretty(raw_waste) AS waste

FROM

(

SELECT

'table' AS TYPE,

schemaname,

tablename AS object_name,

round(

CASE

WHEN otta = 0 THEN 0.0

ELSE table_bloat.relpages / otta::NUMERIC

END,

1

) AS bloat,

CASE

WHEN relpages < otta THEN '0'

ELSE(

bs*(

table_bloat.relpages - otta

)::BIGINT

)::BIGINT

END AS raw_waste

FROM

table_bloat

UNION SELECT

'index' AS TYPE,

schemaname,

tablename || '::' || iname AS object_name,

round(

CASE

WHEN iotta = 0

OR ipages = 0 THEN 0.0

ELSE ipages / iotta::NUMERIC

END,

1

) AS bloat,

CASE

WHEN ipages < iotta THEN '0'

ELSE(

bs*(

ipages - iotta

)

)::BIGINT

END AS raw_waste

FROM

index_bloat

) bloat_summary

ORDER BY

raw_waste DESC,

bloat DESC;



来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69994931/viewspace-2850606/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
瀚高PG实验室(Highgo PG Lab)依托于瀚高DBA运维团队及瀚高数据库PG内核研发团队,旨在深入研究PostgreSQL技术、使用技巧、内核探秘、PG教学等,并进行分享。欢迎大家关注、交流。

注册时间:2021-02-18

  • 博文量
    184
  • 访问量
    126074