2008-11-15 13 views
6

que tienen la siguiente estructura de la tabla¿Qué tan malo es tener un índice único y normal en la misma columna?

CREATE TABLE `table` (
    `id` int(11) NOT NULL auto_increment, 
    `date_expired` datetime NOT NULL, 
    `user_id` int(11) NOT NULL, 
    `foreign_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `date_expired` (`date_expired`,`user_id`,`foreign_id`), 
    KEY `user_id` (`user_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

Como se dará cuenta, no tengo índices duplicados en user_id: date_expired & user_id. Por supuesto, quiero el índice único porque quiero asegurarme de que los datos sean únicos.

El motivo de los índices duplicados es que sin el índice user_id, mi consulta de búsqueda principal tarda 4 segundos. Con el índice extra, demora 1 segundo. La consulta se está uniendo a la tabla en user_id y marcando date_expired.

La tabla solo tiene 275 registros.

  • ¿Qué tan malo es tener un índice único y normal en el mismo campo?
  • ¿Qué tan malo es tener índices más grandes que los datos cuando la tabla es puramente ids?

Respuesta

8

creo que si ha creado su índice único como (user_id, date_expired, foreign_id), obtendrá el mismo beneficio de tener un índice normal sobre user_id con sólo el índice único. MySQL puede usar las primeras columnas de cualquier índice para reducir el número de filas en la unión de la misma manera que un índice en user_id.

Consulte MySQL's index documentation para obtener más información.

¿Te refieres a la columna auto_increment id en otro lugar de tu esquema para ahorrar espacio? Dado que su índice exclusivo cubre todas las demás columnas de su tabla, en esencia es una clave principal en sí misma y podría descartarse si no lo está.

Puede verificar qué teclas está usando su consulta prefijando con EXPLAIN.

+0

¡Excelente, no lo sabía! Y eso es todo lo que necesitaba hacer. –

+0

Tengo la clave principal porque el sistema básico de administración de bases de datos de usuario que uso requiere que tenga una clave principal. Tienes razón, realmente no lo necesito, pero me hace la vida más fácil y dudo que tenga mucho efecto en la velocidad. –

+0

Genial, PostgreSQL también hace algo similar http://www.postgresql.org/docs/8.2/static/indexes-multicolumn.html Digo esto porque alguien podría estar preguntándose como si fuera un lugar común :-) –

1

Tener varios índices que incluyen un campo no está nada mal (esencialmente, indexan cosas diferentes). Tiene un ligero impacto en el rendimiento de escritura, pero esa es la típica solución de compromiso que tiene con cada índice en primer lugar. Tener índices consumiendo más espacio que los datos en sí no es malo si el espacio es barato. En su caso, debería ser barato dado el hecho de que tiene una cantidad realmente pequeña de entradas.

La pregunta que haría en su posición es: ¿cómo afecta tanto la indexación de una tabla tan pequeña al tiempo de ejecución de mi consulta? Quizás estás haciendo algo mal (pienso en muchas posibles consultas redundantes a esta tabla), ya que una sola debería estar lejos de este rango de tiempo con este pequeño número de entradas).

+0

Hay 20 tablas en la consulta. Este es el que hizo la mayor diferencia cuando se elimina. –

3

No entiendo lo que quiere decir con índices duplicados. Tiene tres índices en la tabla:

  1. Uno para la clave primaria 'id' (lo que implica única)
  2. Otro único para la combinación de 'date_expired', 'user_id', y 'foreign_id'
  3. y un tercero sobre 'user_id' sólo

lo que no hay duplicación, tiene tres diferentes índices que van a hacer cosas diferentes. Necesitas el número 3 para acelerar las consultas relacionadas con user_id, que es lo que estás viendo. Entonces, no hay nada de malo en esta mesa en particular, no estás duplicando nada. En cuanto a la segunda pregunta, depende de sus necesidades, pero ciertamente no es malo para tener más espacio utilizado en los índices que en los datos.

Lo que sería malo, por ejemplo, es tener UNIQUE ('user_id') y luego una KEY ('user_id') (ni siquiera estoy seguro de si MySQL lo permitirá) porque un índice contendría el otro y no hay nada que ganar

Cuestiones relacionadas