Mejores prácticas a seguir con índices de bases de datos [cerrado]

17

¿Cuáles son algunas DO y DONT para mejorar el rendimiento de la base de datos usando el índice?

Un DO sería un caso en el que se debería crear un índice u otro consejo relacionado con los índices que mejorará el rendimiento.

Un DONT será un caso en el que no se debe crear un índice u otra acción relacionada con el índice que pueda dañar el rendimiento.

Haga clic en Upvote
fuente
3
profile, profile, profile
GrandmasterB

Respuestas:

15

Esto depende en parte de para qué se utilizará la base de datos, ya que en general los índices ralentizan las inserciones y actualizaciones y aceleran las consultas. En un almacén de datos, generalmente no hay actualizaciones e inserciones en lotes, lo que facilita la creación de índices y muchas consultas, que se aceleran con muchos índices. En una base de datos en línea para ventas web y similares, hay muchas inserciones y actualizaciones, por lo que tener más de unos pocos índices cuidadosamente seleccionados lo ralentizará.

Si recibe muchas consultas de un tipo específico, podría crear un índice para la consulta, aunque eso es más para el procesamiento en línea que para los almacenes de datos. Si ciertas columnas aparecen mucho en las consultas, es posible que desee un índice en esa columna, y esto es especialmente útil para los almacenes de datos, que se consultan de muchas maneras diferentes y a menudo impredecibles.

Cada vez que agregue o elimine un índice, intente hacer una prueba de rendimiento para ver qué efecto tiene. Sin eso, estás disparando a ciegas.

Hay libros sobre consultas de ajuste y bases de datos, a menudo específicas para un sistema de base de datos y el uso de las herramientas de ese RDBMS. Sin embargo, si necesita optimizar mucho la base de datos, está ejecutando una operación grande y probablemente deba contratar a un DBA con la experiencia adecuada.

David Thornley
fuente
17

Depende en gran medida de cómo use sus tablas. No hay una respuesta única y simple.

El mejor consejo que puedo darle es: use un asesor de ajuste . Analizarán los comandos de la base de datos mientras está utilizando la aplicación, luego realizarán pruebas de carga para proporcionarle consejos significativos.

Existen para SQL Server y Oracle . No sé si otros DBMS los tienen, solo dudo que no proporcionen herramientas tan básicas.

Pocas recomendaciones al azar:

  • Los índices proporcionan ganancias de alto rendimiento cuando se aplican en columnas a menudo incluidas en la cláusula WHERE
  • Use el índice agrupado para la columna más utilizada en sus consultas.
  • No olvide que puede crear múltiples índices con una combinación de columnas (como se usan en sus consultas)
  • Tener muchos índices disminuirá el rendimiento de los comandos INSERT.

Último consejo : si las actuaciones de DB son realmente importantes para su proyecto, contrate a un especialista. Es lo que hice.


fuente
2
+1 para índices en combinaciones de columnas. Índices en columnas ay nob es lo mismo que un índice en (a, b). Este último es casi tan bueno como el índice apara acelerar consultas con una condición activada a, es enormemente mejor para consultas con condiciones activadas ay bno es útil para consultas bsolo. (La mayoría de las bases de datos no lo usarán. Oracle lo hará, pero no obtiene el kilometraje que hace regularmente).
hasta
2
+1, agregaría "aprender a leer planes de consulta para que sepa qué indexar"
Steven A. Lowe
4

@Pierre 303 ya lo dijo, pero lo diré nuevamente. use índices en combinaciones de columnas. Un índice combinado activado (a, b)es solo un poco más lento para las consultas aque un índice activado asolo, y es enormemente mejor si su consulta combina ambas columnas. Algunas bases de datos pueden unir índices en ay bantes de llegar a la tabla, pero esto no es tan bueno como tener un índice combinado. Cuando crea un índice combinado, debe colocar la columna que es más probable que se busque primero en el índice combinado.

Si ésta lo admite, DO puso índices en las funciones que se muestran en las consultas en lugar de columnas. (Si está llamando a una función en una columna, los índices en esa columna son inútiles).

Si está utilizando una base de datos con las verdaderas tablas temporales que se pueden crear y destruir al vuelo (por ejemplo, PostgreSQL, MySQL, pero no Oracle), entonces NO crear índices en tablas temporales.

Si está utilizando una base de datos que le permite (por ejemplo Oracle), DO bloqueo en buenos planes de consulta. Los optimizadores de consultas a lo largo del tiempo cambiarán los planes de consulta. Suelen mejorar el plan. Pero a veces lo hacen dramáticamente peor. En general, no notará mejoras en el plan: la consulta no fue un cuello de botella. Pero un solo mal plan puede derribar un sitio ocupado.

NO tenga índices en las tablas en las que va a realizar una gran carga de datos. Es mucho, mucho más rápido soltar índices, cargar los datos y luego reconstruir los índices que mantenerlos a medida que carga la tabla.

NO use índices en consultas que tengan que acceder a más de una pequeña fracción de una tabla grande. (Lo pequeño depende del hardware. El 5% es una regla práctica decente). Por ejemplo, si tiene datos con nombres y género, los nombres son un buen candidato para la indexación, ya que cualquier nombre representa una pequeña fracción del total de filas. No sería útil indexar por género, ya que aún tendrá que acceder al 50% de las filas. Realmente desea utilizar un escaneo de tabla completo La razón es que los índices terminan accediendo a un archivo grande al azar, lo que hace que necesite búsquedas de disco. Las búsquedas de disco son lentas. Como ejemplo, recientemente logré acelerar una consulta de una hora que se veía así:

SELECT small_table.id, SUM(big_table.some_value)
FROM small_table
  JOIN big_table
    ON big_table.small_table_id = small_table.id
GROUP BY small_table.id

a menos de 3 minutos reescribiéndolo de la siguiente manera:

SELECT small_table.id, big_table_summary.summed_value
FROM small_table
  JOIN (
      SELECT small_table_id, SUM(some_value) as summed_value
      FROM big_table
      GROUP BY small_table_id
    ) big_table_summary
    ON big_table_summary.small_table_id =  small_table.id

lo que obligó a la base de datos a comprender que no debería intentar usar el índice tentador big_table.small_table_id. (Una buena base de datos, como Oracle, debería resolverlo por sí sola. Esta consulta se estaba ejecutando en MySQL).

Actualización: Aquí hay una explicación del punto de búsqueda de disco que hice. Un índice proporciona una búsqueda rápida para indicar dónde están los datos en la tabla. Esto suele ser una victoria, ya que solo verá los datos que necesita ver. Pero no siempre, particularmente si eventualmente analizará muchos datos. Los discos transmiten bien los datos, pero hacen que las búsquedas sean lentas. Una búsqueda aleatoria de datos en el disco toma 1/200 de segundo. La versión lenta de la consulta terminó haciendo algo así como 600,000 de esos y tomó cerca de una hora. (Hizo más búsquedas que eso, pero el almacenamiento en caché captó algunas de ellas). Por el contrario, la versión rápida sabía que tenía que leer todo y transmitir datos a algo así como 70 MB / segundo. Pasó por una tabla de 11 GB en menos de 3 minutos.

btilly
fuente
Hola, estoy confundido por tu ejemplo. Pensé que usar el índice habría acelerado las cosas, ¿no es ese el objetivo de los índices? ¿Está diciendo que si una consulta tuviera acceso a> 5% de una tabla, entonces tener un índice en la columna que está buscando haría las cosas más lentas?
Haga clic en Upvote
@ Haga clic en Upvote: si una consulta accede a más del 5% (fracción exacta altamente dependiente del hardware y los datos) de una tabla, es más rápido no usar un índice para esa consulta. Tener un índice no duele mientras no lo uses. Actualizaré con más detalles sobre por qué es eso.
btilly
Información útil. Más información sobre esto, por ejemplo, mysqlperformanceblog.com/2007/08/28/… Pero me preguntaba si "ignorar la clave" no estaba a la altura de esto, ¿es necesario que sea una subconsulta?
Inca
@Inca: No estaba al tanto de 'ignorar clave'. Cambio las bases de datos lo suficiente como para que a menudo haya cosas específicas de la base de datos que no conozco. Por lo que parece funcionaría, pero significativamente menos eficiente que mi solución final. La diferencia es que eso se uniría, luego se agruparía, mientras que el mío se agruparía, luego se uniría. Esto ahorra trabajo en la unión porque es necesario unir menos registros.
btilly
"Una buena base de datos (p. Ej., Oracle, pero no MySQL)": evite cosas estúpidas de promoción como esa, especialmente cuando ignora el hecho de que MySQL puede usar perfectamente múltiples índices al mismo tiempo (anotó "INDEX MERGE" en los planes de consulta) .
Patrick Allaert
2

HACER: Indice los pocos campos a los que más accede mediante consultas y / o comparaciones.

NO HAGA: Indice cada campo en la tabla pensando que lo hará más rápido.

No tengo ninguna estadística al respecto, pero trato de mantener no más de 4 campos indexados en una tabla si puedo evitarlo. La normalización de mis bases de datos generalmente ayuda a mantener estos números bajos, ya que todo se puede buscar con una tecla numérica (que de todos modos es más rápido). Intento mantenerme alejado de los campos de texto completo para la indexación. Son bastante pesados.

Joel Etherton
fuente
2

Básicamente, los índices aceleran la búsqueda pero ralentizan la escritura y ocupan espacio. Esa es la compensación que se está haciendo.

Cualquier campo que se use con frecuencia para unirse, buscar / comparar u ordenar por es candidato para un índice. Saber que es realmente benéfico, mide. Sin embargo, las claves foráneas de tablas muy unidas con lotes (> 1000s) de registros y pocas inserciones darán resultado.

Para los campos de texto, puede indexar una parte del campo (por ejemplo, los primeros 6 caracteres) que aceleraría su consulta pero aligeraría la carga en los índices. Las búsquedas de texto completo (búsqueda like %substring%) requieren diferentes técnicas, con las que no estoy familiarizado, por lo que no puedo aconsejarle allí.

Una situación importante donde los índices no van a ayudar: no puede usar el índice de los campos de fecha completa o fecha y hora cuando busca (/ unirse / ordenar) en parte de la fecha. Un índice date_createdactivado no lo ayudará con una consulta como select * from t where year(date_created) = 2011. En mysql no puede crear un índice en parte de la fecha. (Cuando usa ' between' en lugar de year()que pueda usar el índice en el campo de fecha).

Más información sobre MYSQL en el manual: http://dev.mysql.com/doc/refman/5.6/en/optimization-indexes.html

Inca
fuente
1

HACER: intente mantener el tamaño total del índice agrupado al mínimo. Las entradas de índice agrupadas se incluirán en otros índices no agrupados y, a partir de aquí, existe la posibilidad de desperdiciar espacio en disco.


fuente
1

Piense en una tabla como un léxico, donde los artículos están ordenados por orden de aparición (o ningún orden útil), y en un índice de tabla como índice de libro para ese léxico.

Utiliza un índice para encontrar rápidamente algo en un libro. En lugar de escanear todo el libro, solo necesita encontrar la clave en el índice (un índice generalmente ordenado de alguna manera (por categoría, por campo científico, por época histórica, etc.), esto también significa que no tendrá que escanear todo el índice) y luego salte a la página correcta.

Sin embargo, a diferencia de un libro, una tabla no se imprime una vez y luego es inmutable. Se actualiza todo el tiempo y, por lo tanto, cada índice debe actualizarse con él. Esto, por supuesto, tiene un costo de espacio y tiempo, que solo puede justificarse por la utilidad de un índice.

Por lo tanto, use un índice para una columna, si esa columna se usa como clave en consultas de búsqueda frecuentes, y no use una, si no es así. La palabra frecuente es un buen cuantificador, cuando se habla en general. Al final, tendrá que hacer una buena estimación de cuáles son frecuentes, luego simplemente comparar el rendimiento con o sin índice en caso de duda.

back2dos
fuente