2010-06-15 25 views
162

He estado usando índices en mis bases de datos MySQL desde hace un tiempo pero nunca correctamente aprendí acerca de ellos. En general, pongo un índice en los campos que voy a buscar o seleccionando usando una cláusula WHERE, pero a veces no me parece tan blanco y negro.Índices MySQL: ¿cuáles son las mejores prácticas?

¿Cuáles son las mejores prácticas para los índices de MySQL?

Ejemplo situaciones/dilemas:

Si una tabla tiene seis columnas y todos ellos se pueden buscar , en caso de que el índice todos ellos o ninguno de ellos?

.

¿Cuáles son los impactos negativos impactos de indexación?

.

Si tengo una columna VARCHAR 2500, que se puede buscar de las partes de mi sitio, debería hacerlo en un índice?

+3

Probablemente deberías volver a hacer la pregunta. La elección de Índices es una parte importante para la optimización de cualquier modelo de base de datos. Y a mi punto de vista no relacionado con php. – VGE

Respuesta

8

Cargar datos de forma eficaz: Índices acelerar las recuperaciones, pero ralentizan las inserciones y eliminaciones, así como las actualizaciones de los valores en las columnas indizadas. Es decir, los índices ralentizan la mayoría de las operaciones que implican escritura. Esto ocurre porque escribir una fila requiere escribir no solo la fila de datos, también requiere cambios en los índices. Cuantos más índices tenga una tabla, más cambios habrá que hacer y mayor será la degradación del rendimiento promedio. La mayoría de las tablas reciben muchas lecturas y pocas escrituras, pero para una tabla con un alto porcentaje de escrituras, el costo de la actualización del índice puede ser significativo.

Evita índices: Si no es necesario un índice en particular para ayudar a las consultas se desempeñan mejor, no crearlo.

Espacio en disco: Un índice ocupa espacio en disco y múltiples índices ocupan correspondientemente más espacio. Esto puede hacer que alcance un límite de tamaño de tabla más rápidamente que si no hay índices. Evite los índices siempre que sea posible.

Para llevar: No más de índice de

3

1/2) Índices acelerar ciertas operaciones de selección pero más lento como otras operaciones de inserción, actualización y eliminaciones. Puede ser un buen equilibrio.

3) el uso de un índice de texto completo o tal vez esfinge

+0

Para evitar 'ralentizar otras operaciones como la inserción, actualización y deletes' puede utilizar ' iniciar la transacción; '' TU CÓDIGO; '' commit' que puede ayudar a evitar la desaceleración 'down' las otras operaciones, como solo verificará una de las restricciones una vez. CAVEAT: Si usa 'REPLACE INTO' y su' SQL_MODE' <> 'STRICT_ALL_TABLES' O' TRADICTIONAL', 'Bulk Load' ignorará el reemplazo e insertará duplicados. – JayRizzo

19

Si una tabla tiene seis columnas y todos ellos se pueden buscar, debo índice de todos ellos o ninguno de ellos

Son ¿Estás buscando campo por campo o hay algunas búsquedas que usan campos múltiples? ¿En qué campos se está buscando más? ¿Cuáles son los tipos de campo? (El índice funciona mejor en INT que en VARCHAR, por ejemplo) ¿Ha intentado utilizar EXPLAIN en las consultas que se están ejecutando?

¿Cuáles son los impactos en el rendimiento de la indexación de negetive

actualizaciones e inserciones será más lenta. También hay requisitos adicionales de espacio de almacenamiento, pero eso no es importante en estos días.

Si tengo una columna VARCHAR 2500, que se pueden realizar búsquedas de partes de mi sitio, debo índice que

No, a menos que sea único (lo que significa que ya está indexada) o si sólo buscar coincide exactamente en ese campo (no utiliza LIKE o la búsqueda de texto completo de mySQL).

Generalmente pongo un índice en cualquier campo que voy a estar buscando o seleccionando utilizando una cláusula WHERE

que había normalmente índice de los campos que son los más consultados, y luego INT/Booleans/ENUMs más bien que los campos que son VARCHARS. No olvide, a menudo necesita crear un índice en campos combinados, en lugar de un índice en un campo individual. Use EXPLAIN y verifique el registro lento.

42

Consulte presentaciones como More Mastering the Art of Indexing.

Actualización 12/2012: He publicado una nueva presentación mía: How to Design Indexes, Really. Presenté esto en octubre de 2012 en ZendCon en Santa Clara, y en diciembre de 2012 en Percona Live London.

Diseñar los mejores índices es un proceso que tiene que coincidir con las consultas que ejecuta en su aplicación.

Es difícil recomendar reglas generales sobre qué columnas son las mejores para indexar, o si debe indexar todas las columnas, sin columnas, qué índices deben abarcar varias columnas, etc. Depende de las consultas que necesita ejecutar .

Sí, hay algunos gastos generales por lo que no debe crear índices innecesariamente. Pero debe crear los índices que dan beneficio a las consultas que necesita para ejecutar rápidamente. La sobrecarga de un índice generalmente es superado por su beneficio.

para una columna que es VARCHAR (2500), es probable que desee utilizar un FULLTEXT index o un índice de prefijo:

CREATE INDEX i ON SomeTable(longVarchar(100)); 

Tenga en cuenta que un índice convencional no puede ayudar si usted está buscando las palabras que puede estar en el medio de ese largo varchar. Para eso, use un índice de texto completo.

+2

Muchas gracias. http://www.slideshare.net/matsunobu/more-mastering-the-art-of-indexing?next_slideshow=1 fue muy útil. – RY35

37

no voy a repetir algunos de los buenos consejos en otras respuestas, pero añadirá:

Índices compuestos

Puede crear índices compuestos - un índice que incluye múltiples columnas. MySQL puede usar estos desde a la izquierda a a la derecha.Así que si usted tiene:

Table A 
Id 
Name 
Category 
Age 
Description 

si tiene un índice compuesto que incluye Nombre/Categoría/Edad en ese orden, estas cláusulas WHERE usarían el índice:

WHERE Name='Eric' and Category='A' 

WHERE Name='Eric' and Category='A' and Age > 18 

pero

WHERE Category='A' and Age > 18 

no usaría ese índice porque todo tiene que ser usado de izquierda a derecha.

Explicar

Uso Explicar/Explicar extendido para entender lo que se dispone de índices de MySQL y de cuál se selecciona realidad. MySQL solo usará UNA clave por consulta.

EXPLAIN EXTENDED SELECT * from Table WHERE Something='ABC' 

lento registro de consultas

Encienda el slow query log para ver qué consultas se están ejecutando lento.

columnas de ancho

Si usted tiene una amplia columna donde la mayoría de la distinción sucede en los primeros caracteres, se pueden utilizar sólo los primeros N caracteres en su índice. Ejemplo: Tenemos una columna ReferenceNumber definida como varchar (255) pero el 97% de los casos, el número de referencia es de 10 caracteres o menos. Cambié el índice para ver solo los primeros 10 caracteres y mejoré bastante el rendimiento.

+0

Tengo una pregunta sobre la última parte. Leí en alguna parte que si creas una columna con VARCHAR siempre deberías establecerla en 255. Ahora dijiste que un índice establecido para este tipo de columna podría limitarse a mirar solo los primeros 10 caracteres. ¿Cómo puedes hacer eso exactamente? – AlexioVay

+0

Will 'WHERE Name = 'Eric' and Age> 18' work? –

188

Definitivamente, debe dedicar un tiempo a leer sobre la indexación, hay mucho escrito al respecto, y es importante comprender lo que está sucediendo.

En términos generales, el índice impone un orden en las filas de una tabla.

Por simplicidad, imagine que una tabla es solo un gran archivo CSV. Cuando se inserta una fila, se inserta al final. Entonces el orden "natural" de la tabla es solo el orden en que se insertaron las filas.

Imagine que tiene ese archivo CSV cargado en una aplicación de hoja de cálculo muy rudimentaria. Todo lo que hace esta hoja de cálculo es mostrar los datos y numera las filas en orden secuencial.

Ahora imagine que necesita encontrar todas las filas que tienen algún valor "M" en la tercera columna. Dado lo que tienes disponible, solo tienes una opción. Escanea la tabla comprobando el valor de la tercera columna para cada fila. Si tienes muchas filas, ¡este método (un "escaneo de tabla") puede llevar mucho tiempo!

Ahora imagina que, además de esta tabla, tienes un índice. Este índice en particular es el índice de valores en la tercera columna. El índice enumera todos los valores de la tercera columna, en un orden significativo (por ejemplo, alfabéticamente) y para cada uno de ellos, proporciona una lista de números de fila donde aparece ese valor.

Ahora tiene una buena estrategia para encontrar todas las filas donde el valor de la tercera columna es "M". Por ejemplo, puede realizar un binary search!Mientras que la exploración de tabla requiere que busque N filas (donde N es el número de filas), la búsqueda binaria solo requiere que observe las entradas de índice log-n, en el peor de los casos. ¡Guau, eso es mucho más fácil!

Por supuesto, si tiene este índice y está agregando filas a la tabla (al final, ya que así es como funciona nuestra tabla conceptual), debe actualizar el índice todas las veces. Así que haces un poco más de trabajo mientras escribes filas nuevas, pero ahorras mucho tiempo cuando estás buscando algo.

Por lo tanto, en general, la indexación crea una compensación entre la eficacia de lectura y la eficiencia de escritura. Sin índices, las inserciones pueden ser muy rápidas: el motor de base de datos simplemente agrega una fila a la tabla. A medida que agrega índices, el motor debe actualizar cada índice mientras realiza la inserción.

Por otro lado, las lecturas se vuelven mucho más rápidas.

Afortunadamente eso cubre sus dos primeras preguntas (como otros han respondido, usted necesita encontrar el equilibrio correcto).

Su tercer escenario es un poco más complicado. Si está utilizando LIKE, los motores de indexación generalmente le ayudarán con su velocidad de lectura hasta el primer "%". En otras palabras, si está SELECCIONANDO DONDE la columna LIKE 'foo% bar%', la base de datos usará el índice para buscar todas las filas donde la columna comienza con "foo", y luego deberá escanear ese conjunto de filas intermedio para encontrar el subconjunto que contiene "barra" SELECCIONAR ... DONDE la columna LIKE '% bar%' no puede usar el índice. Espero que puedas ver por qué.

Finalmente, debe comenzar a pensar en los índices en más de una columna. El concepto es el mismo, y se comporta de manera similar a lo LIKE: esencialmente, si tiene un índice en (a, b, c), el motor continuará usando el índice de izquierda a derecha lo mejor que pueda. Entonces, una búsqueda en la columna a podría usar el índice (a, b, c), como lo haría uno en (a, b). Sin embargo, el motor necesitaría hacer una exploración completa de la tabla si estuviera buscando DONDE b = 5 Y c = 1)

Espero que esto ayude a arrojar algo de luz, pero debo reiterar que es mejor que gaste unas pocas horas hurgando en busca de buenos artículos que expliquen estas cosas en profundidad. También es una buena idea leer la documentación de su servidor de base de datos en particular. La forma en que los planificadores de consultas implementan y usan los índices puede variar ampliamente.

+8

¿Qué pasa con los índices 'FULLTEXT'? ¿Pueden ayudar con condiciones como 'LIKE '% bar%''? – Septagram

4

En general, los índices ayudan a acelerar la búsqueda en la base de datos, teniendo la desventaja de usar espacio extra en el disco y ralentizar las consultas INSERT/UPDATE/DELETE. Use EXPLAIN y lea los resultados para saber cuándo MySQL usa sus índices.

Si una tabla tiene seis columnas y todas ellas se pueden buscar, ¿debo indexarlas todas o ninguna de ellas?

La indexación de las seis columnas no siempre es la mejor práctica.

(a) ¿Va a utilizar alguna de esas columnas al buscar información específica?

(b) ¿Cuál es la selectividad de esas columnas (cuántos valores distintos hay almacenados, en comparación con la cantidad total de registros en la tabla)?

MySQL utiliza un optimizador basado en costos, que trata de encontrar la ruta "más barata" al realizar una consulta. Y los campos con baja selectividad no son buenos candidatos.

¿Cuáles son los impactos negativos en el rendimiento de la indexación?

Ya respondida: espacio en disco adicional, menor rendimiento durante la inserción - actualización - eliminar.

Si tengo una columna VARCHAR 2500 que se puede buscar desde partes de mi sitio, ¿debería indexarla?

Pruebe el FULLTEXT Index.

Cuestiones relacionadas