如何确定非分区表高水位虚高
Posted 当年亦如是
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何确定非分区表高水位虚高相关的知识,希望对你有一定的参考价值。
如何确定非分区表高水位虚高:
一般认为分配给表使用的数据块空间远大于表实际占用存储空间时,我们就认为表的高水位虚高,涉及该表的查询sql存在不必要的消耗,需要进行优化。
通过比较数据占用和分配数据块的空间比对来确定哪些表的高水位虚高:
sys用户执行(如果数据库支持statistics_level配置,一般9.2之后都支持):
SQL>exec dbms_stats.FLUSH_DATABASE_MONITORING_INFO();
再执行:
SELECT a.owner || ‘.‘ || a.table_name "Table",
a.num_rows,
a.avg_row_len,
b.inserts,
b.deletes,
a.num_rows + nvl(b.inserts, 0) - nvl(b.deletes, 0) total_rows,
round(a.avg_row_len *(a.num_rows + nvl(b.inserts, 0) - nvl(b.deletes, 0)) / 1024 / 1024,4) "Calculate_Sizle(Mb)估算的大小",
c.bytes / 1024 / 1024 "Segment_Size(Mb)段大小",
(a.avg_row_len * (a.num_rows + nvl(b.inserts, 0) - nvl(b.deletes, 0))) /c.bytes "使用率"
FROM dba_tables a
LEFT JOIN all_tab_modifications b
ON a.owner = b.table_owner
AND a.table_name = b.table_name
INNER JOIN dba_segments c ON a.owner = c.owner
AND a.table_name = c.segment_name
WHERE a.last_analyzed IS NOT NULL
AND a.partitioned = ‘NO‘
--AND b.deletes
> 0
AND a.owner LIKE ‘%DLP114_SXU01%‘
AND a.table_name LIKE ‘DEBUG_MSG‘
--AND c.bytes /
1024 / 1024 > 100
--AND (a.avg_row_len * (a.num_rows + nvl(b.inserts, 0) - nvl(b.deletes, 0))) / c.bytes
< 0.3
ORDER BY b.deletes DESC;
注意: 如果数据库不支持statistics_level配置的话,请使用数据库用户对表单独执行ANALYZE后查看。
Sql中关键条件说明:
avg_row_len * (a.num_rows + nvl(b.inserts, 0) - nvl(b.deletes, 0))) / c.bytes < 0.3:表单条数据的平均占用空间*当前数据条数=表数据理论占用数据块大小,c.byte是表实际占用的数据块大小。用这两个比率来分析出表占用的数据块的实际使用率。
c.bytes / 1024 / 1024 > 100:表实际占用数据块大小,对于表实际占用很小的表来说,认为消耗是可以接受的,可以认为不具优化价值,可以选择忽略这些表的虚高。
以上是关于如何确定非分区表高水位虚高的主要内容,如果未能解决你的问题,请参考以下文章
Linux 内核 内存管理分区伙伴分配器 ⑦ ( z->watermark[WMARK_MIN] 最低水位计算 | min_free_kbytes 初始化 )
Linux 内核 内存管理分区伙伴分配器 ⑦ ( z->watermark[WMARK_MIN] 最低水位计算 | min_free_kbytes 初始化 )
Linux 内核 内存管理分区伙伴分配器 ⑥ ( zone 结构体中水线控制相关成员 | 在 Ubuntu 中查看内存区域水位线 )