Oracle에서 테이블 크기를 계산하는 방법
익숙해져 그로 인해 이 없어질 도 있다)MSSQL
테이블 사이즈를 어떻게 구할 수 있는지 궁금합니다.Oracle
에 10g만큼 되었습니다 구글에서 검색해 봤기 때문에 지금처럼 쉬운 옵션이 없다는 것을 알게 되었습니다.sp_spaceused
여전히 제가 얻은 잠재적인 답변은 대부분 시대에 뒤떨어져 있거나 효과가 없습니다.아마도 현재 작업 중인 스키마에서 DBA가 아니기 때문일 것입니다.
솔루션이나 권장사항을 알고 계십니까?
이 쿼리에 관심이 있을 수 있습니다.테이블 상의 인덱스 및 LOB를 고려하여 각 테이블에 할당되는 공간의 양을 나타냅니다.테이블 자체뿐만 아니라 "인덱스를 포함한 구매 주문 테이블이 차지하는 공간"에 관심이 있는 경우가 많습니다.당신은 언제든지 세부사항을 조사할 수 있습니다.이를 위해서는 DBA_* 뷰에 액세스해야 합니다.
COLUMN TABLE_NAME FORMAT A32
COLUMN OBJECT_NAME FORMAT A32
COLUMN OWNER FORMAT A10
SELECT
owner,
table_name,
TRUNC(sum(bytes)/1024/1024) Meg,
ROUND( ratio_to_report( sum(bytes) ) over () * 100) Percent
FROM
(SELECT segment_name table_name, owner, bytes
FROM dba_segments
WHERE segment_type IN ('TABLE', 'TABLE PARTITION', 'TABLE SUBPARTITION')
UNION ALL
SELECT i.table_name, i.owner, s.bytes
FROM dba_indexes i, dba_segments s
WHERE s.segment_name = i.index_name
AND s.owner = i.owner
AND s.segment_type IN ('INDEX', 'INDEX PARTITION', 'INDEX SUBPARTITION')
UNION ALL
SELECT l.table_name, l.owner, s.bytes
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.segment_name
AND s.owner = l.owner
AND s.segment_type IN ('LOBSEGMENT', 'LOB PARTITION')
UNION ALL
SELECT l.table_name, l.owner, s.bytes
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.index_name
AND s.owner = l.owner
AND s.segment_type = 'LOBINDEX')
WHERE owner in UPPER('&owner')
GROUP BY table_name, owner
HAVING SUM(bytes)/1024/1024 > 10 /* Ignore really small tables */
ORDER BY SUM(bytes) desc
;
-- Tables + Size MB
select owner, table_name, round((num_rows*avg_row_len)/(1024*1024)) MB
from all_tables
where owner not like 'SYS%' -- Exclude system tables.
and num_rows > 0 -- Ignore empty Tables.
order by MB desc -- Biggest first.
;
--Tables + Rows
select owner, table_name, num_rows
from all_tables
where owner not like 'SYS%' -- Exclude system tables.
and num_rows > 0 -- Ignore empty Tables.
order by num_rows desc -- Biggest first.
;
주의: 통계 수집을 통해 보다 정확하게 산출된 추정치는 다음과 같습니다.
exec dbms_utility.analyze_schema(user,'COMPUTE');
우선, 일반적으로 공간 분석을 위해 테이블 통계를 수집하는 것은 잠재적으로 위험한 일이라고 경고합니다.통계정보를 수집하면 쿼리 계획이 변경될 수 있습니다.특히 DBA가 콜이 사용하지 않는 기본값 이외의 파라미터를 사용하는 통계정보 수집 작업을 설정하고 있는 경우 Oracle은 해당 테이블을 사용하는 쿼리를 다시 해석하여 퍼포먼스에 영향을 줄 수 있습니다.없이 일부 (DBA의 경우 ).OPTIMIZER_MODE
통계 수집을 통해 Oracle이 규칙 기반 최적화 도구 사용을 중지하고 일련의 쿼리에 비용 기반 최적화 도구 사용을 시작할 수 있습니다. 이러한 작업이 운영 환경에서 예기치 않게 수행될 경우 큰 성능 문제가 될 수 있습니다.할 수 .USER_TABLES
(오류)ALL_TABLES
★★★★★★★★★★★★★★★★★」DBA_TABLES
하지 않고 직접 참조할 수 있습니다.GATHER_TABLE_STATS
만약 당신의 통계가 정확하지 않다면, 아마도 그것에 대한 이유가 있을 것이고 당신은 현상을 방해하고 싶지 않을 것이다.
Server에 SQL Server입니다.sp_spaceused
Oracle의 이 높습니다.DBMS_SPACE
패키지.Tom Kyte는 이 패키지에 간단한 인터페이스를 제공하고 다음과 같은 정보를 출력하는 훌륭한 절차를 가지고 있습니다.sp_spaceused
력합니니다다
먼저 테이블에서 옵티마이저 통계를 수집합니다(아직 수집하지 않은 경우).
begin
dbms_stats.gather_table_stats('MYSCHEMA','MYTABLE');
end;
/
경고: Justin이 답변에서 말한 바와 같이, 최적화 통계 수집은 질의 최적화에 영향을 미치므로 충분한 주의와 고려 없이 수행해서는 안 됩니다.
그런 다음 생성된 통계에서 테이블이 점유하고 있는 블록 수를 찾습니다.
select blocks, empty_blocks, num_freelist_blocks
from all_tables
where owner = 'MYSCHEMA'
and table_name = 'MYTABLE';
테이블에 할당된 블록의 총 수는 blocks + empty_blocks + num_freelist_blocks입니다.
블럭은 실제로 데이터를 포함하는 블럭 수입니다.
블록 수에 사용 중인 블록 크기(일반적으로 8KB)를 곱하여 17블록 x 8KB = 136KB와 같은 공간을 확보합니다.
스키마 내의 모든 테이블에 대해 동시에 이를 수행하려면 다음 절차를 수행합니다.
begin
dbms_stats.gather_schema_stats ('MYSCHEMA');
end;
/
select table_name, blocks, empty_blocks, num_freelist_blocks
from user_tables;
주의: 이 AskTom 스레드를 읽은 후 위의 내용을 변경합니다.
자세한 정보를 제공하기 위해 WW의 쿼리를 수정했습니다.
SELECT * FROM (
SELECT
owner, object_name, object_type, table_name, ROUND(bytes)/1024/1024 AS meg,
tablespace_name, extents, initial_extent,
ROUND(Sum(bytes/1024/1024) OVER (PARTITION BY table_name)) AS total_table_meg
FROM (
-- Tables
SELECT owner, segment_name AS object_name, 'TABLE' AS object_type,
segment_name AS table_name, bytes,
tablespace_name, extents, initial_extent
FROM dba_segments
WHERE segment_type IN ('TABLE', 'TABLE PARTITION', 'TABLE SUBPARTITION')
UNION ALL
-- Indexes
SELECT i.owner, i.index_name AS object_name, 'INDEX' AS object_type,
i.table_name, s.bytes,
s.tablespace_name, s.extents, s.initial_extent
FROM dba_indexes i, dba_segments s
WHERE s.segment_name = i.index_name
AND s.owner = i.owner
AND s.segment_type IN ('INDEX', 'INDEX PARTITION', 'INDEX SUBPARTITION')
-- LOB Segments
UNION ALL
SELECT l.owner, l.column_name AS object_name, 'LOB_COLUMN' AS object_type,
l.table_name, s.bytes,
s.tablespace_name, s.extents, s.initial_extent
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.segment_name
AND s.owner = l.owner
AND s.segment_type = 'LOBSEGMENT'
-- LOB Indexes
UNION ALL
SELECT l.owner, l.column_name AS object_name, 'LOB_INDEX' AS object_type,
l.table_name, s.bytes,
s.tablespace_name, s.extents, s.initial_extent
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.index_name
AND s.owner = l.owner
AND s.segment_type = 'LOBINDEX'
)
WHERE owner = UPPER('&owner')
)
WHERE total_table_meg > 10
ORDER BY total_table_meg DESC, meg DESC
/
IIRC에 필요한 테이블은 DBA_입니다.표, DBA_EXTENS 또는 DBA_Segments 및 DBA_데이터 파일또한 테이블에는 USER_버전과 ALL_버전이 있습니다.머신에 대한 관리 권한이 없는지 확인할 수 있습니다.
하위 파티션 테이블 및 인덱스에 대해 다음 쿼리를 사용할 수 있습니다.
SELECT owner, table_name, ROUND(sum(bytes)/1024/1024/1024, 2) GB
FROM
(SELECT segment_name table_name, owner, bytes
FROM dba_segments
WHERE segment_type IN ('TABLE', 'TABLE PARTITION', 'TABLE SUBPARTITION')
UNION ALL
SELECT i.table_name, i.owner, s.bytes
FROM dba_indexes i, dba_segments s
WHERE s.segment_name = i.index_name
AND s.owner = i.owner
AND s.segment_type IN ('INDEX', 'INDEX PARTITION', 'INDEX SUBPARTITION')
UNION ALL
SELECT l.table_name, l.owner, s.bytes
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.segment_name
AND s.owner = l.owner
AND s.segment_type = 'LOBSEGMENT'
UNION ALL
SELECT l.table_name, l.owner, s.bytes
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.index_name
AND s.owner = l.owner
AND s.segment_type = 'LOBINDEX')
WHERE owner in UPPER('&owner')
GROUP BY table_name, owner
HAVING SUM(bytes)/1024/1024 > 10 /* Ignore really small tables */
ORDER BY SUM(bytes) DESC
;
WW에 대한 답변은 위에서 설명한 바와 같이 파티션과 하위 파티션과 TYPE: 테이블/인덱스/LOB 등을 표시하는 컬럼을 포함합니다.
SELECT
owner, "Type", table_name "Name", TRUNC(sum(bytes)/1024/1024) Meg
FROM
( SELECT segment_name table_name, owner, bytes, 'Table' as "Type"
FROM dba_segments
WHERE segment_type in ('TABLE','TABLE PARTITION','TABLE SUBPARTITION')
UNION ALL
SELECT i.table_name, i.owner, s.bytes, 'Index' as "Type"
FROM dba_indexes i, dba_segments s
WHERE s.segment_name = i.index_name
AND s.owner = i.owner
AND s.segment_type in ('INDEX','INDEX PARTITION','INDEX SUBPARTITION')
UNION ALL
SELECT l.table_name, l.owner, s.bytes, 'LOB' as "Type"
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.segment_name
AND s.owner = l.owner
AND s.segment_type IN ('LOBSEGMENT','LOB PARTITION','LOB SUBPARTITION')
UNION ALL
SELECT l.table_name, l.owner, s.bytes, 'LOB Index' as "Type"
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.index_name
AND s.owner = l.owner
AND s.segment_type = 'LOBINDEX')
WHERE owner in UPPER('&owner')
GROUP BY table_name, owner, "Type"
HAVING SUM(bytes)/1024/1024 > 10 /* Ignore really small tables */
ORDER BY SUM(bytes) desc;
select segment_name,segment_type,bytes/1024/1024 MB
from dba_segments
where segment_name='TABLENAME' and owner ='OWNERNAME' order by mb desc;
테이블 영역별 스키마 크기를 가져오기 위해 쿼리를 수정했습니다.
SELECT owner,
tablespace_name,
TRUNC (SUM (bytes) / 1024 / 1024) Meg,
ROUND (ratio_to_report (SUM (bytes)) OVER () * 100) Percent
FROM (SELECT tablespace_name, owner, bytes
FROM dba_segments
WHERE segment_type IN
('TABLE', 'TABLE PARTITION', 'TABLE SUBPARTITION')
UNION ALL
SELECT i.tablespace_name, i.owner, s.bytes
FROM dba_indexes i, dba_segments s
WHERE s.segment_name = i.index_name
AND s.owner = i.owner
AND s.segment_type IN
('INDEX', 'INDEX PARTITION', 'INDEX SUBPARTITION')
UNION ALL
SELECT l.tablespace_name, l.owner, s.bytes
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.segment_name
AND s.owner = l.owner
AND s.segment_type IN ('LOBSEGMENT', 'LOB PARTITION')
UNION ALL
SELECT l.tablespace_name, l.owner, s.bytes
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.index_name
AND s.owner = l.owner
AND s.segment_type = 'LOBINDEX')
WHERE owner IN UPPER ('&owner')
GROUP BY owner, tablespace_name
--HAVING SUM(bytes)/1024/1024 > 10 /* Ignore really small tables */
ORDER BY tablespace_name -- desc
;
"테이블 크기"가 무슨 뜻인지에 따라 다르죠.테이블은 파일 시스템의 특정 파일과 관련이 없습니다.테이블은 테이블스페이스(파티셔닝되어 있는 경우 여러 테이블스페이스, 테이블의 인덱스를 고려하는 경우 여러 테이블스페이스)에 배치됩니다.테이블스페이스에는 여러 테이블이 포함되어 있는 경우가 많아 여러 파일에 분산되어 있을 수 있습니다.
향후 테이블 확장에 필요한 공간을 예상하는 경우 avg_row_len에 테이블 내의 행 수(또는 테이블 내의 예상되는 행 수)를 곱한 것이 좋은 가이드입니다.그러나 Oracle은 각 블록에 일부 공간을 남겨두는데, 이는 부분적으로 행이 업데이트될 경우 다른 전체 행을 해당 블록에 장착할 수 없기 때문입니다(예: 8K 블록은 대부분의 행 크기보다 훨씬 큰 3K의 2개 행에만 해당).So BLOCKS (USER_의 경우)표)가 더 나은 가이드일 수 있습니다.
그러나 테이블에 200,000개의 행이 있고 그 중 절반은 삭제되어도 테이블은 여전히 같은 수의 블록을 '소유'합니다.다른 테이블에서 사용할 수 있도록 해제되지 않습니다.또한 블록은 개별적으로 테이블에 추가되지 않고 '확장'이라고 불리는 그룹으로 추가됩니다.따라서 일반적으로 EMTEMY_BLOCKS(USER_에도 있음)가 있습니다.TABLES)를 선택합니다.
분할된 테이블에 대한 수정:
SELECT owner, table_name, ROUND(sum(bytes)/1024/1024/1024, 2) GB FROM (SELECT segment_name table_name, owner, bytes FROM dba_segments WHERE segment_type IN ('TABLE', 'TABLE PARTITION', 'TABLE SUBPARTITION') UNION ALL SELECT i.table_name, i.owner, s.bytes FROM dba_indexes i, dba_segments s WHERE s.segment_name = i.index_name AND s.owner = i.owner AND s.segment_type IN ('INDEX', 'INDEX PARTITION', 'INDEX SUBPARTITION') UNION ALL SELECT l.table_name, l.owner, s.bytes FROM dba_lobs l, dba_segments s WHERE s.segment_name = l.segment_name and s.owner = l.owner AND s.segment_type in ('LOBSEGMENT', 'LOB PARTITION', 'LOB SUBPARTITION') UNION ALL SELECT l.table_name, l.owner, s.bytes FROM dba_lobs l, dba_segments s WHERE s.segment_name = l.index_name AND s.owner = l.owner AND s.segment_type = 'LOBINDEX') WHERE owner in UPPER('&owner') GROUP BY table_name, owner HAVING SUM(bytes)/1024/1024 > 10 /* Ignore really small tables */ order by sum(bytes) desc ;
블록 크기에 따라 테이블의 원시 크기를 반환하는 단순 선택 항목(색인이 있는 크기 포함)
table_name, (dba_size에서 select sum(blocks)을 선택합니다.(여기서 dba_select sum(blocks) b, a.index_name=b.segment_name 및 a.table_name=blocks_s.table_name,0)+blocks)*8192/total Size를 dba_s로 설정합니다.
나는 이것이 조금 더 정확하다는 것을 알았다.
SELECT
owner, table_name, TRUNC(sum(bytes)/1024/1024/1024) GB
FROM
(SELECT segment_name table_name, owner, bytes
FROM dba_segments
WHERE segment_type in ('TABLE','TABLE PARTITION')
UNION ALL
SELECT i.table_name, i.owner, s.bytes
FROM dba_indexes i, dba_segments s
WHERE s.segment_name = i.index_name
AND s.owner = i.owner
AND s.segment_type in ('INDEX','INDEX PARTITION')
UNION ALL
SELECT l.table_name, l.owner, s.bytes
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.segment_name
AND s.owner = l.owner
AND s.segment_type IN ('LOBSEGMENT','LOB PARTITION')
UNION ALL
SELECT l.table_name, l.owner, s.bytes
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.index_name
AND s.owner = l.owner
AND s.segment_type = 'LOBINDEX')
---WHERE owner in UPPER('&owner')
GROUP BY table_name, owner
HAVING SUM(bytes)/1024/1024 > 10 /* Ignore really small tables */
ORDER BY SUM(bytes) desc
select segment_name as tablename, sum(bytes/ (1024 * 1024 * 1024)) as tablesize_in_GB
From dba_segments /* if looking at tables not owned by you else use user_segments */
where segment_name = 'TABLE_WHOSE_SIZE_I_WANT_TO_KNOW'
and OWNER = 'WHO OWNS THAT TABLE' /* if user_segments is used delete this line */
group by segment_name ;
조인에서 "선택" 크기를 가져올 수 있는 옵션이 하나 더 있으며 테이블 크기도 옵션으로 사용할 수 있습니다.
-- 1
EXPLAIN PLAN
FOR
SELECT
Scheme.Table_name.table_column1 AS "column1",
Scheme.Table_name.table_column2 AS "column2",
Scheme.Table_name.table_column3 AS "column3",
FROM Scheme.Table_name
WHERE ;
SELECT * FROM TABLE (DBMS_XPLAN.display);
테이블 데이터, 테이블 인덱스 및 BLOB 필드의 세그먼트를 계산하는 이전 모델과 동일한 변형이 있습니다.
CREATE OR REPLACE FUNCTION
SYS.RAZMER_TABLICY_RAW(pNazvanie in varchar, pOwner in varchar2)
return number
is
val number(16);
sz number(16);
begin
sz := 0;
--Calculate size of table data segments
select
sum(t.bytes) into val
from
sys.dba_segments t
where
t.segment_name = upper(pNazvanie)
and
t.owner = upper(pOwner);
sz := sz + nvl(val,0);
--Calculate size of table indexes segments
select
sum(s.bytes) into val
from
all_indexes t
inner join
dba_segments s
on
t.index_name = s.segment_name
where
t.table_name = upper(pNazvanie)
and
t.owner = upper(pOwner);
sz := sz + nvl(val,0);
--Calculate size of table blob segments
select
sum(s.bytes) into val
from
all_lobs t
inner join
dba_segments s on t.segment_name = s.segment_name
where
t.table_name = upper(pNazvanie)
and
t.owner = upper(pOwner);
sz := sz + nvl(val,0);
return sz;
end razmer_tablicy_raw;
출처.
언급URL : https://stackoverflow.com/questions/264914/how-do-i-calculate-tables-size-in-oracle
'programing' 카테고리의 다른 글
Keycloak 각도 'Access-Control-Allow-Origin' 헤더가 없습니다. (0) | 2023.03.19 |
---|---|
타이프스크립트에서 오브젝트 속성을 결합하는 방법 (0) | 2023.03.19 |
재스민:비동기 콜백이 재스민에 의해 지정된 타임아웃 내에 호출되지 않았습니다.디폴트_타임아웃_간격 (0) | 2023.03.19 |
PHP json_decode()는 유효한 것처럼 보이는 JSON을 사용하여 NULL을 반환합니까? (0) | 2023.03.19 |
Peeee 모델에서 JSON으로 (0) | 2023.03.19 |