MySQL에서 테이블의 데이터 크기 및 인덱스 크기를 추정 / 예측하는 방법


26

나는 발견하고 테이블의 크기를 추정하는 가장 좋은 방법이 무엇인지 내가 블로그와 포럼 만의 연구 된 많은이 있는지에 대한 어떤 정확한 답을 찾을 수 없습니다

예를 들어 , InnoDB 엔진 이있는 City 테이블 이 있으며 , 향후 1 년 내에 100 만 개의 레코드를 갖게되므로이 기간 동안 해당 테이블의 예상 데이터 크기 및 인덱스 크기는 얼마입니까?

mysql> desc City;
+-------------+----------+------+-----+---------+----------------+
| Field       | Type     | Null | Key | Default | Extra          |
+-------------+----------+------+-----+---------+----------------+
| ID          | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name        | char(35) | NO   |     |         |                |
| CountryCode | char(3)  | NO   | MUL |         |                |
| District    | char(20) | NO   |     |         |                |
| Population  | int(11)  | NO   |     | 0       |                |
+-------------+----------+------+-----+---------+----------------+
5 rows in set (0.03 sec)

최신 정보

백만 개의 레코드가있는 예상 상한 (최대 테이블 크기)은 무엇이며 어떻게 추정 할 수 있습니까?


대단하다. 그러나 색인 크기 열을 현명하게 얻을 수 있습니다. 의미는 5 개의 열이 색인 된 테이블이있는 경우입니다. 각각의 색인 크기를 얻을 수 있습니까? 나는 이것을 다른 질문으로 물을 것이다. 감사
Sushil

답변:


51

테이블 설명이 주어지면

  • 데이터 행당 66 바이트
  • 기본 키의 행당 4 바이트
  • 국가 코드 색인의 경우 행당 7 바이트
    • 국가의 경우 3 바이트
    • 국가 코드에 첨부 된 클러스터 키의 경우 4 바이트
  • 총 77 바이트의 데이터 및 키
  • 이것은 BTREE 또는 테이블 스페이스 단편화에 대한 하우스 키핑을 고려하지 않습니다.

백만 행의 경우 77,000,000 바이트 (73.43MB)

주어진 테이블 mydb.mytable에 대해 테이블을 측정 할 때이 쿼리를 실행할 수 있습니다.

SELECT 
    CONCAT(FORMAT(DAT/POWER(1024,pw1),2),' ',SUBSTR(units,pw1*2+1,2)) DATSIZE,
    CONCAT(FORMAT(NDX/POWER(1024,pw2),2),' ',SUBSTR(units,pw2*2+1,2)) NDXSIZE,
    CONCAT(FORMAT(TBL/POWER(1024,pw3),2),' ',SUBSTR(units,pw3*2+1,2)) TBLSIZE
FROM
(
    SELECT DAT,NDX,TBL,IF(px>4,4,px) pw1,IF(py>4,4,py) pw2,IF(pz>4,4,pz) pw3
    FROM 
    (
        SELECT data_length DAT,index_length NDX,data_length+index_length TBL,
        FLOOR(LOG(IF(data_length=0,1,data_length))/LOG(1024)) px,
        FLOOR(LOG(IF(index_length=0,1,index_length))/LOG(1024)) py,
        FLOOR(LOG(data_length+index_length)/LOG(1024)) pz
        FROM information_schema.tables
        WHERE table_schema='mydb'
        AND table_name='mytable'
    ) AA
) A,(SELECT 'B KBMBGBTB' units) B;

데이터베이스 및 스토리지 엔진별로 그룹화 된 모든 테이블을 측정하려면

SELECT
    IF(ISNULL(DB)+ISNULL(ENGINE)=2,'Database Total',
    CONCAT(DB,' ',IFNULL(ENGINE,'Total'))) "Reported 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;

이러한 쿼리를 실행하면 데이터베이스 / 엔진 디스크 사용량의 변경 사항을 추적 할 수 있습니다.

시도 해봐 !!!


1
이것은 모든 테이블 크기를 보는 데 매우 유용한 쿼리입니다.
ghayes

CHAR당신이 경우 길이는 3 곱해야합니다 CHARSET utf8. 계산을 두 배로 늘리거나 세 배로 전체 오버 헤드를 추정 할 수 있습니다.
Rick James

@RolandoMySQLDBA, 실제 크기 (압축 테이블)와 비교하고 압축 비율을 얻는 목표로 테이블의 "실제"행 크기를 계산할 수 있는지 알고 있습니까?
ceinmart

@ceinmart innodb_page_size는 고정되어 있으며 (기본적으로 16K 또는 16384) 행과 그룹화 또는 분할되는 경계가됩니다. innodb_page_size를 변경하면 데이터 저장이 좋거나 나쁘게 변경 될 수 있습니다. 행이 채워지거나 희박한 정도에 따라 (특히 TEXT / BLOB / VARCHAR이있는 경우). 기껏해야 .ibd 파일의 크기와 스키마 보고서의 비율을 비교하여 비율을 추정해야합니다. ALTER TABLE ... ENGINE=InnoDB;정확한 비율을 얻으려면 NULL ALTER TABLE ( )을 수행해야 할 수도 있습니다 . 노력은 그만한 가치가 없을 수 있습니다.
RolandoMySQLDBA

@ceinmart innodb_page_size 변경은 테이블 단위 설정이 아닙니다. 데이터를 완전히 내 보내야 합니다 ( mariadb.com/kb/en/library/how-to-change-innodb_page_size 참조 )
RolandoMySQLDBA

4

InnoDB 테이블을 사용하는 경우에서 데이터 / 개별 인덱스의 크기를 얻을 수 있습니다 mysql.innodb_index_stats. 'size'통계에는 답이 페이지 단위로 포함되므로 페이지 크기 ( 기본적으로 16K) 를 곱해야합니다 .

select database_name, table_name, index_name, stat_value*@@innodb_page_size
from mysql.innodb_index_stats where stat_name='size';

인덱스 PRIMARY는 데이터 자체입니다.


1
이것은 테이블에 데이터가 있다고 가정합니다. OP가 채우기 전에 예상하고 싶어하는 것 같습니다.
Rick James

0
SELECT  Table_NAME "tablename",
           data_length   "table data_length in Bytes",
           index_length  "table index_length in Bytes",
           data_free  "Free Space in Bytes"
    FROM  information_schema.TABLES  where  Table_schema = 'databasename';

당신은 크기가 익숙해 질 수있는이 쿼리를 실행하여 DataIndex테이블을, 당신은 행의 #에 대해이 크기를 확인 할 수 있으며 100 만 행에 대한 예측


1
확실하지 않지만 정확한 결과를 얻을 수 있습니까? 이것을 테스트 해 본 적이 있습니까?
압둘 마나프

실제로 나는이 쿼리 결과를 주기적으로 테스트하여 성장 (%) wrt 크기를
보았습니다.

0

아직 데이터가없는 경우 몇 가지 팁이 있습니다. 다음은 InnoDB에 적용됩니다. (MyISAM은 훨씬 간단하고 작습니다.)

CHAR가변 길이 열에는 사용하지 마십시오 . 뭐CHARACTER SET 을 사용하고 있습니까? Ascii는 문자 당 1 바이트가 필요합니다. utf8mb4는 1과 4 사이가 필요합니다.

4 bytes per INT
35 for CHAR(35), if ascii or latin1; varchar is probably less
3 for the country code; it is fixed length
etc

총계 = 약 80 바이트

다양한 오버 헤드를 설명하기 위해 80에 2와 3 사이를 곱하십시오. 1M 행 테이블은 대부분 160MB와 240MB 사이입니다.

단일 인덱스를 측정하려면 (예 CountryCode: 3 바이트)

3 bytes data
4 bytes for the PK (implicitly included with any secondary key)
25 bytes basic overhead
32 total
times 1.5 -- overhead for BTree that was randomly inserted into
48MB -- total for 1M rows.

노트:

  • BTree의 리프 노드 만 계산하면됩니다. 비 리프 노드의 오버 헤드는 일반적으로 1 %입니다.

  • PRIMARY KEY데이터로, 그래서를 계산 할 필요가 없다 "클러스터"입니다.

  • 명시 적 PK가없는 경우 조작 된 PK를 허용하려면 행 크기에 6 바이트를 추가해야합니다.

  • ROW_FORMAT = COMPRESSED2 : 1 수축에 대해 알려줍니다. (이는 일반적인 압축 압축률 3 : 1의 압축률보다 좋지 않습니다.)

  • SHOW TABLE STATUS LIKE "tablename";'실제'크기를 계산하는 빠른 방법입니다. Data_length데이터 및 PK를 참조하십시오 . Index_length보조 인덱스 및 Data_free기타 항목에 대해.

  • Index_length를 초과하는 경우는 드 rare니다 Data_length. 그러나 그 일이 "잘못"되지는 않습니다.


-1

지루하다. 그러나 세부 사항은 문서에 있습니다.

거의 필요하지 않은 최대한 정확하게하려면 테이블 구조 및 인덱스 구조에 대해서도 읽어야합니다.

내가 당신의 신발 안에 있다면, 나는 테이블을 만들고 백만 행의 테스트 데이터로 채우고 크기 변화를 측정 할 것입니다. 응용 프로그램에 따라 트랜잭션 로그 파일의 크기도 고려해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.