2011-04-19 13 views
12

Tengo una base de datos con las siguientes estadísticasÍndice de MySQL es más grande que los datos almacenados

Tables  Data Index Total 
11  579,6 MB 0,9 GB 1,5 GB 

Así como se puede ver el índice está cerca de 2 veces más grande. Y hay una tabla con ~ 7 millones de filas que ocupa al menos el 99% de esto.

También tienen dos índices que son muy similares

a) UNIQUE KEY `idx_customer_invoice` (`customer_id`,`invoice_no`), 
b) KEY `idx_customer_invoice_order` (`customer_id`,`invoice_no`,`order_no`) 

actualización: Esta es la definición de la tabla (al menos estructuralmente) de la mesa más grande

CREATE TABLE `invoices` (
    `id` int(10) unsigned NOT NULL auto_increment, 
    `customer_id` int(10) unsigned NOT NULL, 
    `order_no` varchar(10) default NULL, 
    `invoice_no` varchar(20) default NULL, 
    `customer_no` varchar(20) default NULL, 
    `name` varchar(45) NOT NULL default '', 
    `archived` tinyint(4) default NULL, 
    `invoiced` tinyint(4) default NULL, 
    `time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 
    `group` int(11) default NULL, 
    `customer_group` int(11) default NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `idx_customer_invoice` (`customer_id`,`invoice_no`), 
    KEY `idx_time` (`time`), 
    KEY `idx_order` (`order_no`), 
    KEY `idx_customer_invoice_order` (`customer_id`,`invoice_no`,`order_no`) 
) ENGINE=InnoDB AUTO_INCREMENT=9146048 DEFAULT CHARSET=latin1 | 

Actualización 2:

mysql> show indexes from invoices; 
+----------+------------+----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| Table | Non_unique | Key_name     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | 
+----------+------------+----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 
| invoices |   0 | PRIMARY     |   1 | id   | A   |  7578066 |  NULL | NULL |  | BTREE  |   | 
| invoices |   0 | idx_customer_invoice  |   1 | customer_id | A   |   17 |  NULL | NULL |  | BTREE  |   | 
| invoices |   0 | idx_customer_invoice  |   2 | invoice_no | A   |  7578066 |  NULL | NULL | YES | BTREE  |   | 
| invoices |   1 | idx_time     |   1 | time  | A   |  541290 |  NULL | NULL |  | BTREE  |   | 
| invoices |   1 | idx_order     |   1 | order_no | A   |  6091 |  NULL | NULL | YES | BTREE  |   | 
| invoices |   1 | idx_customer_invoice_order |   1 | customer_id | A   |   17 |  NULL | NULL |  | BTREE  |   | 
| invoices |   1 | idx_customer_invoice_order |   2 | invoice_no | A   |  7578066 |  NULL | NULL | YES | BTREE  |   | 
| invoices |   1 | idx_customer_invoice_order |   3 | order_no | A   |  7578066 |  NULL | NULL | YES | BTREE  |   | 
+----------+------------+----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+ 

Mis preguntas son:

  1. ¿Hay una manera de encontrar índices utilizados en MySQL?
  2. ¿Hay errores comunes que afectan el tamaño del índice?
  3. ¿Puede el índice A eliminarse de forma segura?
  4. ¿Cómo se puede medir el tamaño de cada índice? Todo lo que obtengo es el total de todos los índices.
+0

Sería útil si ejecutara algunas tablas 'show create's para cualquier tabla grande y publicara la salida. –

Respuesta

10

Puede eliminar el índice A, porque, como ha notado, es un subconjunto de otro índice. Y es posible hacer esto sin interrumpir el procesamiento normal.

El tamaño de los archivos de índice no es alarmante en sí mismo y puede ser cierto que el beneficio neto es positivo. En otras palabras, la utilidad y el valor de un índice no deben descontarse porque da como resultado un archivo grande.

El diseño de índice es un arte complejo y sutil que implica una comprensión profunda de las explicaciones del optimizador de consultas y pruebas exhaustivas. Pero un error común es incluir muy pocos campos en un índice para hacerlo más pequeño. Otra es probar los índices con datos insuficientes o insuficientemente representativos.

+3

Estoy de acuerdo con el "arte sutil". –

1

¿Hay una manera de encontrar índices utilizados en MySQL?

El optimizador de motor de base de datos seleccionará un índice adecuado al intentar optimizar su consulta. Dependiendo de la última vez que recopiló estadísticas sobre sus índices, el índice elegido variará. Los índices no utilizados podrían utilizarse repentinamente debido a la nueva distribución de datos.

Puede indiceA eliminarse de manera segura?

Yo diría que sí, si indexA e indexB son índices de B-Tree. Esto se debe a que un índice que comienza con las mismas columnas en el mismo orden tendrá la misma estructura.

+0

Para las otras dos preguntas, no estoy seguro de poder responder correctamente. – Benoit

+1

Todos los índices son B-Tree –

1

uso

show indexes from table; 

a definir lo que los índices tiene usted en una tabla en particular. Cardinality diría cuán útil es tu índice.

Puede eliminar sus índices de seguridad (que no se romperá una mesa), pero cuidado: algunas consultas pueden ejecutar más lento. Primero debe analizar sus consultas para decidir si necesita un determinado índice o no.

no creo que usted puede descubrir longitud de datos de un índice en particular, sin embargo.

PERO, creo que probablemente pienses que si la longitud de los índices es mayor que la longitud de los datos dos veces es algo anormal ... Bueno, estás equivocado.Todos sus índices pueden ser útiles;) Si tiene una tabla que proporciona mucha información y tiene que buscar en una gran cantidad de columnas, fácilmente puede ser que los índices de esta tabla tengan un tamaño 2 veces mayor que las tablas de datos.

+0

¿Puede especificar cómo la cardinalidad se corresponde con la utilidad? Y los índices están ahí por una razón, el rendimiento de las consultas en esta tabla es crítico para la aplicación. –

+0

Pero, me alegra saber que no es anormal al menos ...: P –

+0

Se dice en la documentación oficial: "Cuanto mayor es la cardinalidad, mayor es la probabilidad de que MySQL use el índice al hacer combinaciones". Prácticamente significa que esta columna se usará en uniones más veces que en otras con baja cardinalidad. La evaluación de cardinalidad se basa en estadísticas. ¿Cómo exactamente? Bueno ... No sé :) También es cierto que si la cardinalidad es alta, este índice consume más volumen ya que "la cardinalidad es una estimación del número de valores únicos en el índice". – Nemoden

0
  1. indiceA puede eliminar porque hay una indiceB incluyen indiceA
  2. el impacto que la longitud de su índice es el tipo de columna y longitud de la columna
  3. uso:

    seleccione Index_length de INFORMATION_SCHEMA.TABLES donde table_name = 'your_table_name' y table_schema = 'your_db_name';

    obtener su tabla Index_length

+0

3. Esto me da un número, 1003831296, ¿qué significa? –

+0

@La longitud del índice de Peter Lindqvist es 1003831296B; también puede usar el estado de mostrar tabla como 'su_nombre_tabla' – Neo

+0

Hmm, me gustaría ver el tamaño de los índices individuales. –

6

Puedo estar equivocado, pero el primer índice (idx_customer_invoice) es único, la segunda (idx_customer_invoice_order) no es, por lo que es probable que pierda la restricción de unicidad cuando se quita eso. ¿No?

Cuestiones relacionadas