크기 추정시 인덱스가 차지하는 공간의 양을 고려 했습니까? 또한 텍스트 필드가 ( N[VAR]CHAR
가 아닌 [VAR]CHAR
) 멀티 바이트로 설정되고 입력 파일이 UTF-8 또는 문자 당 일반 1 바이트 인 경우 스토리지 요구 사항을 최대 2 배까지 높일 수 있습니다. 또한 테이블에 클러스터 된 키 / 인덱스가있는 경우이 크기는 테이블의 다른 모든 인덱스에 영향을 미치므로 모든 행에 대한 클러스터 된 키 값이 포함 되므로 테이블에 NCHAR (10 지능이 할 것이며, 그 클러스터 된 키 / 당신이뿐만 아니라 데이터 페이지에 행 당 여분의 16 바이트를 사용하는 인덱스 당신은 또한에 행 당 16 바이트를 낭비입니다) 키를 해당 테이블에서 다른 모든 인덱스 ) .
또한 DB 엔진이 삭제 후 할당 된 공간을 남겨 두어 해당 테이블의 새 데이터에 빠르게 다시 사용할 수 있거나 삽입 및 삭제 패턴이 많은 페이지 만 남았 기 때문에 일부 공간이 할당되었지만 사용되지 않습니다. 완전한.
당신은 실행할 수 있습니다 :
SELECT o.name
, SUM(ps.reserved_page_count)/128.0 AS ReservedMB
, SUM(ps.used_page_count)/128.0 AS UsedMB
, SUM(ps.reserved_page_count-ps.used_page_count)/128.0 AS DiffMB
FROM sys.objects o
JOIN sys.dm_db_partition_stats ps ON o.object_id = ps.object_id
WHERE OBJECTPROPERTYEX(o.object_id, 'IsMSShipped') = 0
GROUP BY o.name
ORDER BY SUM(ps.reserved_page_count) DESC
어떤 테이블이 공간을 차지하는지 빠르게 살펴볼 수 있습니다.
또한 EXEC sp_spaceused
해당 DB 내에서 실행하면 두 개의 결과 집합이 반환됩니다. 첫 번째는 데이터 파일에 대해 파일 시스템에 할당 된 총 공간과 할당되지 않은 공간의 양을 나열하고 두 번째는 할당 된 공간이 데이터 페이지, 인덱스 페이지 또는 현재 사용되지 않은 공간의 양을 나열합니다.
sp_spaceused
주어진 객체가 사용하는 공간도 반환하므로 분석을 위해 테이블을 빌드하기 위해 이것을 반복 할 수 있습니다.
-- TEMP TABLES FOR ANALYSIS
CREATE TABLE #tTables (sName NVARCHAR(MAX), iRows BIGINT, iReservedKB BIGINT, iDataKB BIGINT, iIndexKB BIGINT, iUnusedKB BIGINT)
CREATE TABLE #tTmp (sName NVARCHAR(MAX), iRows BIGINT, sReservedKB NVARCHAR(MAX), sDataKB NVARCHAR(MAX), sIndexKB NVARCHAR(MAX), sUnusedKB NVARCHAR(MAX))
-- COLLECT SPACE USE PER TABLE
EXEC sp_msforeachtable 'INSERT #tTmp EXEC sp_spaceused [?];'
-- CONVERT NUMBER-AS-TEXT COLUMNS TO NUMBER TYPES FOR EASIER ANALYSIS
INSERT #tTables SELECT sName, iRows
, CAST(REPLACE(sReservedKB, ' KB', '') AS BIGINT)
, CAST(REPLACE(sDataKB , ' KB', '') AS BIGINT)
, CAST(REPLACE(sIndexKB , ' KB', '') AS BIGINT)
, CAST(REPLACE(sUnusedKB , ' KB', '') AS BIGINT)
FROM #tTmp
DROP TABLE #tTmp
-- DO SOME ANALYSIS
SELECT sName='TOTALS', iRows=SUM(iRows), iReservedKB=SUM(iReservedKB), iDataKB=SUM(iDataKB), iIndexKB=SUM(iIndexKB), iUnusedKB=SUM(iUnusedKB) FROM #tTables ORDER BY sName
SELECT * FROM #tTables ORDER BY iReservedKB DESC
-- CLEAN UP
DROP TABLE #tTables
위의 코드는 모든 테이블 크기를 하나의 목록과 총계에 대한 단일 행으로 출력합니다. 필요한 경우 위의 첫 번째 쿼리 sys.objects
와 같이 다양한 시스템 뷰를 사용하여 자세한 내용 sys.dm_db_partition_stats
은 http://technet.microsoft.com/en-us/library/ms177862.aspx 를 참조하십시오. 각 인덱스가 사용하는 공간
데이터 파일에는 세 가지 클래스의 사용되지 않은 공간이 있습니다.
- 아무것도 할당되지 않은 것 (이것은
sp_spaceused
객체가 지정되지 않은 첫 번째 결과 집합에 표시 됩니다)
- 객체에 할당되었지만 (예약 됨) 현재 사용되지 않은 것 (이것은
sp_spaceused
의 출력 에서 "사용되지 않은"카운트로 표시됩니다 .
- 부분적으로 사용되는 페이지에 잠겨 있습니다 (모든 것이 단일 페이지 청크로 할당되며 한 페이지는 8,192 바이트 길이로 사용됨). 감지 / 계산이 더 어렵습니다. 두 가지 요소가 혼합되어 있습니다.
- 분할 페이지. 데이터가 추가됨에 따라 빈 페이지 부분이 종종 생길 수 있습니다 (스토리지 엔진 은 항상 페이지 내용을 정규화 할 수 있지만 매우 비효율적입니다). I / O 부하는 일반적으로 훨씬 가치가)에서.
- 스토리지 엔진은 여러 페이지에 걸쳐 행을 분할하지 않습니다 (이는 행당 8,192 바이트 제한이 시작되는 페이지 크기와 함께). 행의 크기가 고정되어 있고 각각 1,100 바이트를 차지하는 경우 해당 테이블에 할당 된 각 데이터 블록의 최소 492 바이트를 "폐기"시키게됩니다 (7 개의 행은 7,700 바이트를 취하고 8 번째는 적합하지 않으므로 나머지 바이트는 ' 사용하지 마십시오). 행이 넓을수록 더 나빠질 수 있습니다. 가변 길이 행을 가진 테이블 / 인덱스 (완전히 고정 된 길이의 행보다 훨씬 흔함)는 일반적으로 더 우수하지만 문제를 계산하기는 쉽지 않습니다.
또 다른 경고는 큰 물체 ( TEXT
열,[N]VARCHAR(MAX)
특정 크기를 초과하는 값 등)가 페이지 외부에 배치되면 다른 행의 데이터에 대한 포인터를 보유하기 위해 기본 행 데이터에서 8 바이트를 가져 와서 행 당 8,192 바이트를 제한 할 수 있습니다.
tl; dr : 예상 데이터베이스 크기를 추정하는 것은 처음에 가정하는 것보다 훨씬 복잡 할 수 있습니다.