Cómo estimar / predecir el tamaño de los datos y el tamaño del índice de una tabla en MySQL

26

Estoy encontrando cuál es la mejor manera de estimar el tamaño de una tabla para la que he estudiado muchos blogs y foros pero no puedo encontrar ninguna respuesta precisa

Por ejemplo, tenemos una tabla Ciudad con motor InnoDB , digamos que en el futuro (en el próximo 1 año) tendrá 1 millón de registros, ¿cuál será el tamaño de datos estimado y el tamaño de índice de esa tabla en este período?

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)

ACTUALIZAR

¿Cuál será el límite superior estimado (tamaño máximo de la tabla) con 1 millón de registros y cómo podemos estimarlo?

Abdul Manaf
fuente
Esto es genial. pero es posible obtener el tamaño del índice de la columna sabia. Lo que significa es si tiene una tabla con (digamos) 5 columnas indexadas. ¿Podemos obtener el tamaño del índice de cada uno de ellos? Haré esto como otra pregunta. gracias
Sushil

Respuestas:

51

Dada la descripción de la tabla, veo

  • 66 bytes por fila de datos
  • 4 bytes por fila para la clave primaria
  • 7 bytes por fila para el índice de código de país
    • 3 bytes para el país
    • 4 bytes para la clave agrupada adjunta al código del país
  • Total de 77 bytes de datos y claves.
  • Esto no tiene en cuenta la limpieza para BTREE o la fragmentación del espacio de tabla

Para un millón de filas, eso sería 77,000,000 bytes (73.43 MB)

En cuanto a la medición de la tabla, para una tabla dada mydb.mytable, puede ejecutar esta consulta

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;

Para medir todas las tablas agrupadas por Motor de base de datos y almacenamiento

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;

Ejecute estas consultas y podrá realizar un seguimiento de los cambios en el uso de la base de datos / disco del motor.

Darle una oportunidad !!!

RolandoMySQLDBA
fuente
1
Esta es una gran consulta para ver todos los tamaños de su tabla.
ghayes
Las CHARlongitudes deben multiplicarse por 3 si es así CHARSET utf8. La sobrecarga completa puede estimarse duplicando o triplicando el cálculo.
Rick James
@RolandoMySQLDBA, ¿sabe si es posible calcular el tamaño de fila "real" de una tabla con el objetivo de compararlo con el tamaño real (tabla comprimida) y obtener la proporción de compresión?
ceinmart
@ceinmart innodb_page_size es fijo (16K o 16384 por defecto) y se convierte en el límite donde las filas se agrupan o se dividen. Cambiar innodb_page_size puede alterar el almacenamiento de datos para bien o para mal. Dependiendo de cuán llena o escasa es una fila (especialmente con la presencia de TEXT / BLOB / VARCHAR). En el mejor de los casos, debe comparar el tamaño del archivo .ibd con el que informa el esquema para estimar una relación. También es posible que deba realizar una TABLA DE ALTERACIÓN NULA ( ALTER TABLE ... ENGINE=InnoDB;) para obtener una proporción precisa. Es posible que el esfuerzo no valga la pena.
RolandoMySQLDBA
@ceinmart Tenga en cuenta que cambiar innodb_page_size no es una configuración tabla por tabla. Debería realizar una exportación completa de los datos (consulte mariadb.com/kb/en/library/how-to-change-innodb_page_size )
RolandoMySQLDBA
4

Si está utilizando tablas InnoDB, puede obtener el tamaño de los datos / índices individuales mysql.innodb_index_stats. La estadística de "tamaño" contiene la respuesta, en páginas, por lo que debe multiplicarla por el tamaño de página, es decir, 16 KB de forma predeterminada .

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

El índice PRIMARIO son los datos en sí.

Vajk Hermecz
fuente
1
Esto supone que tiene datos en la tabla; Parece que el OP quiere estimar antes de poblar.
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';

Al ejecutar esta consulta, puede obtener el tamaño utilizado para Datay Indexde una tabla. Puede verificar este tamaño con el número de filas y predecir 1 millón de filas.

Peter Venderberghe
fuente
1
No estoy seguro, pero ¿esto dará algunos resultados precisos? ¿Has probado esto alguna vez?
Abdul Manaf
En realidad, estoy probando el resultado de esta consulta periódicamente para ver el crecimiento (%) del tamaño del wrt
Peter Venderberghe
0

Si aún no tiene datos, aquí hay algunos consejos. Lo siguiente se aplica a InnoDB. (MyISAM es mucho más simple y más pequeño).

No lo use CHARpara columnas de longitud variable. Que CHARACTER SETestas usando Ascii necesita un byte por carácter; utf8mb4 necesita entre 1 y 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

Total = aproximadamente 80 bytes.

Multiplique los 80 por entre 2 y 3 para tener en cuenta varios gastos generales. Lo más probable es que la tabla de filas de 1M tenga entre 160 MB y 240 MB.

Para medir un solo índice, por ejemplo CountryCodede 3 bytes:

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.

Notas:

  • Solo se deben calcular los nodos hoja (de BTrees); la sobrecarga para los nodos no hoja es típicamente del 1%.

  • El PRIMARY KEYse "agrupa" con los datos, por lo que no es necesario calcularlo.

  • Si no tiene una PK explícita, debe agregar 6 bytes al tamaño de la fila para permitir la PK fabricada.

  • ROW_FORMAT = COMPRESSEDle da una contracción de 2: 1. (Esto no es tan bueno como la tasa de compresión típica de zip (etc.) de 3: 1).

  • SHOW TABLE STATUS LIKE "tablename";es la forma rápida de calcular el tamaño 'real'. Ver Data_lengthpara datos y PK; Index_lengthpara índices secundarios y Data_freepara algunas otras cosas.

  • Es raro Index_lengthque exceda Data_length. Sin embargo, no está "mal" que eso suceda.

Rick James
fuente
-1

Es tedioso Pero los detalles están en los documentos .

Para ser lo más preciso posible, lo que rara vez es necesario, también deberá leer sobre la estructura de la tabla y la estructura del índice.

Si estuviera en su lugar, construiría la tabla, la llenaría con un millón de filas de datos de prueba y mediría el cambio de tamaño. Dependiendo de su aplicación, es posible que también deba tener en cuenta el tamaño de los archivos de registro de transacciones.

Mike Sherrill 'Retiro del gato'
fuente