統計 oracle 下某個表下的表和索引的總大小


##for oracle

問題目的是,找到oracle 下所有大表的 表和該表的索引總大小。這樣可以方便開發統計 該表實際占用大小。

 

參考文檔

http://www.51testing.com/html/60/n-846960-2.html

 

感謝


set linesize 140
set pagesize 160

clear breaks
clear computes

break on TABLE_NAME skip 2 ON INDEX_NAME ON INDEX_TYPE ON MB
compute sum of NR_EXEC on TABLE_NAME SKIP 2
compute sum of MB on TABLE_NAME SKIP 2


SET TIMI OFF
set linesize 140
set pagesize 10000
set verify off
col OWNER noprint
col TABLE_NAME for a30 heading 'Table name'
col INDEX_NAME for a30 heading 'Index name'
col INDEX_TYPE for a15 heading 'Index type'
col INDEX_OPERATION for a21 Heading 'Index operation'
col NR_EXEC for 9G999G990 heading 'Executions'
col MB for 999G990D90 Heading 'Index|Size MB' justify right


SELECT
S.OWNER A_OWNER,
TABLE_NAME A_TABLE_NAME,
INDEX_NAME A_INDEX_NAME,
INDEX_TYPE A_INDEX_TYPE,
SUM(S.bytes) / 1048576 A_MB
FROM DBA_SEGMENTS S,
DBA_INDEXES I
WHERE S.OWNER = 'DBMGR'
AND I.OWNER = 'DBMGR'
AND INDEX_NAME = SEGMENT_NAME
GROUP BY S.OWNER, TABLE_NAME, INDEX_NAME, INDEX_TYPE
HAVING SUM(S.BYTES) > 1048576 * 100

 

#########sample 0.1

單獨對某個表ABLE_NAME='d0_BILL'  進行分析,統計這個表的大小和他對應的索引大小,但是不包括總大小,缺點是沒計算所以是否是分區索引,


SELECT
S.OWNER A_OWNER,
TABLE_NAME A_TABLE_NAME,
INDEX_NAME A_INDEX_NAME,
INDEX_TYPE A_INDEX_TYPE,
SUM(S.bytes) / 1048576 A_MB
FROM DBA_SEGMENTS S,
DBA_INDEXES I
WHERE INDEX_NAME = SEGMENT_NAME and s.owner=i.owner
GROUP BY S.OWNER, TABLE_NAME, INDEX_NAME, INDEX_TYPE
HAVING SUM(S.BYTES) > 1048576 * 100 AND TABLE_NAME='d0_BILL'
union
SELECT
DS.OWNER A_OWNER,
TABLE_NAME A_TABLE_NAME,
' ',
' ',
SUM(DS.bytes) / 1048576 A_MB
from DBA_SEGMENTS DS,
DBA_tables T
WHERE t.TABLE_NAME = ds.SEGMENT_NAME and Ds.owner=T.owner
GROUP BY dS.OWNER, TABLE_NAME
HAVING SUM(dS.BYTES) > 1048576 * 100 and TABLE_NAME='d0_BILL'

 

###############

 

 ##sample 0  這個報表通過計算最大50個表的數據,(當然也可以把表 的數量從50 改成 100)

然后按照每個對象分別 輸出如下信息: s_owner(用戶名) ,s_sgement_name(表名字),sgment_size (表的大小) 和 sgment_total_size (表加這個表對應的索引大小 總共大小)


DECLARE
x NUMBER := 0;
s_owner varchar2(32);
s_sgement_name varchar2(200);
s_sgement_size varchar2(200);
s_total_size varchar2(200);

CURSOR get_50rows IS SELECT *
FROM (SELECT owner,SEGMENT_NAME, SUM(BYTES) / 1024 / 1024 MB
FROM DBA_SEGMENTS
GROUP BY owner,SEGMENT_NAME, segment_type
having segment_type like '%TABLE%'
ORDER BY 3 DESC)
WHERE ROWNUM < 50;
BEGIN
--DBMS_OUTPUT.PUT_LINE ('First a basic loop without CURSOR FOR LOOP running fine');

---FOR irec IN get_50rows LOOP -- After CONTINUE statement, control should resume here

OPEN get_50rows;
LOOP
FETCH get_50rows INTO s_owner,s_sgement_name,s_sgement_size;

 

SELECT
(SELECT SUM(S.BYTES/1024/1024) -- The table segment size
FROM DBA_SEGMENTS S
WHERE S.OWNER = s_owner AND
(S.SEGMENT_NAME = s_sgement_name)) +
(SELECT NVL(SUM(S.BYTES/1024/1024), 0) -- The Lob Segment Size
FROM DBA_SEGMENTS S, DBA_LOBS L
WHERE S.OWNER = s_owner AND
(L.SEGMENT_NAME = S.SEGMENT_NAME AND L.TABLE_NAME = s_sgement_name AND L.OWNER = s_owner)) +
(SELECT SUM(S.BYTES/1024/1024) -- The Lob Index size
FROM DBA_SEGMENTS S, DBA_INDEXES I
WHERE S.OWNER = s_owner AND
(I.INDEX_NAME = S.SEGMENT_NAME AND I.TABLE_NAME = s_sgement_name AND I.OWNER = s_owner))
"TOTAL TABLE SIZE" into s_total_size
FROM DUAL;

--DBMS_OUTPUT.PUT_LINE ('Inside loop: x = ' || TO_CHAR(x));
x := x + 1;
--IF x < 3 THEN
--CONTINUE;
---END IF;
--DBMS_OUTPUT.PUT_LINE ('Inside loop, after CONTINUE: x = '||TO_CHAR(x));
DBMS_OUTPUT.PUT_LINE(CHR(10));
DBMS_OUTPUT.PUT_LINE('owner_name: '||s_owner);
---DBMS_OUTPUT.PUT_LINE('---------------------------');
---DBMS_OUTPUT.PUT_LINE(CHR(10));
---DBMS_OUTPUT.PUT_LINE('Summary');
DBMS_OUTPUT.PUT_LINE('========');
DBMS_OUTPUT.PUT_LINE('sgment_name: '||s_sgement_name);
DBMS_OUTPUT.PUT_LINE('sgment_size(MB): '||s_sgement_size);
DBMS_OUTPUT.PUT_LINE('sgment_total_size(MB): '||s_total_size);
DBMS_OUTPUT.PUT_LINE('========');
EXIT WHEN x = 51;


END LOOP;
end;
/

 

##sample 0.2  將top 100 segment 存入數據庫對象,方便做excel 統計。也方便做清理前和清理后的數據對比

 


step 1: create table: use store date of top segment size t
create table dbmgr.seg_size_summary
(
time VARCHAR2(30),
owner VARCHAR2(30),
segment_name VARCHAR2(30),
segment_size NUMBER,
segment_tot_size NUMBER
);

COMMENT ON TABLE dbmgr.seg_size_summary IS 'seg_size_summary include top 100 table and index size';


step 2: run procedure
set serveroutput on

DECLARE
x NUMBER := 0;
s_owner varchar2(32);
s_sgement_name varchar2(200);
s_sgement_size varchar2(200);
s_total_size varchar2(200);
v_sysdate varchar2(12);

CURSOR get_50rows IS SELECT *
FROM (SELECT owner,SEGMENT_NAME, SUM(BYTES) / 1024 / 1024 MB
FROM DBA_SEGMENTS
GROUP BY owner,SEGMENT_NAME, segment_type
having segment_type like '%TABLE%'
ORDER BY 3 DESC)
WHERE ROWNUM < 100;
BEGIN
--DBMS_OUTPUT.PUT_LINE ('First a basic loop without CURSOR FOR LOOP running fine');
DBMS_OUTPUT.ENABLE (buffer_size=>null);
---FOR irec IN get_50rows LOOP -- After CONTINUE statement, control should resume here
select to_char(sysdate,'yyyymmdd') into v_sysdate from dual ; --get sysdate

OPEN get_50rows;
LOOP
FETCH get_50rows INTO s_owner,s_sgement_name,s_sgement_size;


SELECT
(SELECT SUM(S.BYTES/1024/1024) -- The table segment size
FROM DBA_SEGMENTS S
WHERE S.OWNER = s_owner AND
(S.SEGMENT_NAME = s_sgement_name)) +
(SELECT NVL(SUM(S.BYTES/1024/1024), 0) -- The Lob Segment Size
FROM DBA_SEGMENTS S, DBA_LOBS L
WHERE S.OWNER = s_owner AND
(L.SEGMENT_NAME = S.SEGMENT_NAME AND L.TABLE_NAME = s_sgement_name AND L.OWNER = s_owner)) +
(SELECT NVL(SUM(S.BYTES/1024/1024), 0) -- The Lob Index size
FROM DBA_SEGMENTS S, DBA_INDEXES I
WHERE S.OWNER = s_owner AND
(I.INDEX_NAME = S.SEGMENT_NAME AND I.TABLE_NAME = s_sgement_name AND I.OWNER = s_owner))
"TOTAL TABLE SIZE" into s_total_size
FROM DUAL;

--DBMS_OUTPUT.PUT_LINE ('Inside loop: x = ' || TO_CHAR(x));
x := x + 1;
--IF x < 3 THEN
--CONTINUE;
---END IF;
--DBMS_OUTPUT.PUT_LINE ('Inside loop, after CONTINUE: x = '||TO_CHAR(x));
DBMS_OUTPUT.PUT_LINE(CHR(10));
DBMS_OUTPUT.PUT_LINE('owner_name: '||s_owner);
---DBMS_OUTPUT.PUT_LINE('---------------------------');
---DBMS_OUTPUT.PUT_LINE(CHR(10));
---DBMS_OUTPUT.PUT_LINE('Summary');
DBMS_OUTPUT.PUT_LINE('========');
DBMS_OUTPUT.PUT_LINE('sgment_name: '||s_sgement_name);
DBMS_OUTPUT.PUT_LINE('sgment_size(MB): '||s_sgement_size);
DBMS_OUTPUT.PUT_LINE('sgment_total_size(MB): '||s_total_size);
DBMS_OUTPUT.PUT_LINE(v_sysdate);
DBMS_OUTPUT.PUT_LINE('========');
insert into dbmgr.seg_size_summary values(v_sysdate,s_owner,s_sgement_name,s_sgement_size,s_total_size);
EXIT WHEN x = 101;


END LOOP;
commit;
end;
/

step 3: view data
select time,owner,segment_name,segment_size "表大小",segment_tot_size "表和索引總大小" from dbmgr.seg_size_summary where time=to_char(sysdate,'yyyymmdd');

 

 ###sampe 0.3 不區分表和索引大小,只是統計排名在前幾位的對象,包括對象類型,比如是否是分區索引和分區表。

檢查10個大對象
select owner, name, type, mega, tbs
from (select owner,
case
when segment_type like 'LOB%' then
logical_name
else
segment_name
end as name,
segment_type as type,
round(bytes / 1024 / 1024) as mega,
tablespace_name as tbs
from (select a.owner,
a.segment_name,
a.segment_type,
b.table_name || '.' || b.column_name as logical_name,
bytes,
a.tablespace_name
from (select owner,
segment_name,
segment_type,
sum(bytes) as bytes,
max(tablespace_name) as tablespace_name
from dba_segments
group by owner, segment_name, segment_type) a,
dba_lobs b
where a.owner = b.owner(+)
and a.segment_name = b.segment_name(+)
and a.bytes > 1024 * 1024 * 1024)
order by bytes desc);

 

 

##sample 1 for mysql

How to find out each table size

 

GOAL

Find out each Schema size by Engine from the MySQL Server

SOLUTION

Extract metadata information about each Database Schema size by Engine utilization and total, for both indexes and data:

SELECT
  IF(ISNULL(DB)+ISNULL(ENGINE)=2,'Instance Total',
  CONCAT(DB,' ',IFNULL(ENGINE,'Total'))) " Statistic",
  LPAD(CONCAT(FORMAT(DAT/POWER(1024,pw1),2),' ',
  SUBSTR(units,pw1*2+1,2)),17,' ') "Data Size",
  LPAD(CONCAT(FORMAT(NDX/POWER(1024,pw2),2),' ',
  SUBSTR(units,pw2*2+1,2)),17,' ') "Index Size",
  LPAD(CONCAT(FORMAT(TBL/POWER(1024,pw3),2),' ',
  SUBSTR(units,pw3*2+1,2)),17,' ') "Total Size"
FROM
(
  SELECT DB,ENGINE,DAT,NDX,TBL,
  IF(px>4,4,px) pw1,IF(py>4,4,py) pw2,IF(pz>4,4,pz) pw3
  FROM
  (SELECT *,
  FLOOR(LOG(IF(DAT=0,1,DAT))/LOG(1024)) px,
  FLOOR(LOG(IF(NDX=0,1,NDX))/LOG(1024)) py,
  FLOOR(LOG(IF(TBL=0,1,TBL))/LOG(1024)) pz
  FROM
  (SELECT
  DB,ENGINE,
  SUM(data_length) DAT,
  SUM(index_length) NDX,
  SUM(data_length+index_length) TBL
  FROM
  (
  SELECT table_schema DB,ENGINE,data_length,index_length FROM
  information_schema.tables WHERE table_schema NOT IN
  ('information_schema','performance_schema','mysql')
  AND ENGINE IS NOT NULL
  ) AAA GROUP BY DB,ENGINE WITH ROLLUP
) AAA) AA) A,(SELECT ' BKBMBGBTB' units) B;

+-------------------+-----------+------------+------------+
| Statistic         | Data Size | Index Size | Total Size |
+-------------------+-------------------+-----------------+
| database1 InnoDB  | 64.00 KB  | 416.00 KB  | 480.00 KB  |
| database1 Total   | 64.00 KB  | 416.00 KB  | 480.00 KB  |
| database2 InnoDB  | 1.22 MB   | 2.81 MB    | 4.03 MB    |
| database2 Total   | 1.22 MB   | 2.81 MB    | 4.03 MB    |
| database3 InnoDB  | 32.00 KB  | 0.00 B     | 32.00 KB   |
| database3 Total   | 32.00 KB  | 0.00 B     | 32.00 KB   |
| database4 InnoDB  | 32.00 KB  | 48.00 KB   | 80.00 KB   |
| database4 Total   | 32.00 KB  | 48.00 KB   | 80.00 KB   |
| database5 InnoDB  | 176.00 KB | 496.00 KB  | 672.00 KB  |
| database5 MyISAM  | 0.00 B    | 1.00 KB    | 1.00 KB    |
| database5 Total   | 176.00 KB | 497.00 KB  | 673.00 KB  |
| database6 InnoDB  | 32.00 KB  | 304.00 KB  | 336.00 KB  |
| database6 Total   | 32.00 KB  | 304.00 KB  | 336.00 KB  |
| sys InnoDB        | 16.00 KB  | 0.00 B     | 16.00 KB   |
| sys Total         | 16.00 KB  | 0.00 B     | 16.00 KB   |
| database7 ARCHIVE | 88.00 B   | 0.00 B     | 88.00 B    |
| database7 InnoDB  | 1.62 MB   | 2.50 MB    | 4.12 MB    |
| database7 Total   | 1.63 MB   | 2.50 MB    | 4.13 MB    |
| Instance Total    | 3.19 MB   | 6.55 MB    | 9.74 MB    |
+-------------------+-----------+------------+------------+
19 rows in set (0.45 sec) 

 

 

########sample 5

https://www.cnblogs.com/chshnan/archive/2012/02/07/2341694.html

ORACLE刪除當前用戶下所有的表的方法

 

 


使用業務用戶登陸,如果沒有刪除用戶的權限,則可以執行:

select 'drop table '||table_name||';'
from cat
where table_type='TABLE'

將會輸出一批刪除表的sql語句,這些SQL語句執行一下就可以了。(需要有drop table的權限)


select 'drop SEQUENCE '||table_name||';'
from cat
where table_type='SEQUENCE';

 

select 'drop VIEW '||table_name||';'
from cat
where table_type='VIEW';

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM