¿Cuántos índices de bases de datos son demasiados?

109

Estoy trabajando en un proyecto con una base de datos Oracle bastante grande (aunque mi pregunta se aplica igualmente bien a otras bases de datos). Tenemos una interfaz web que permite a los usuarios buscar en casi cualquier combinación posible de campos.

Para que estas búsquedas sean más rápidas, estamos agregando índices a los campos y combinaciones de campos en los que creemos que los usuarios buscarán comúnmente. Sin embargo, dado que no sabemos realmente cómo nuestros clientes utilizarán este software, es difícil saber qué índices crear.

El espacio no es una preocupación; tenemos una unidad RAID de 4 terabytes de la cual estamos usando solo una pequeña fracción. Sin embargo, me preocupan las posibles penalizaciones de rendimiento por tener demasiados índices. Debido a que esos índices deben actualizarse cada vez que se agrega, elimina o modifica una fila, imagino que sería una mala idea tener docenas de índices en una sola tabla.

Entonces, ¿cuántos índices se consideran demasiados? 10? 25? 50? ¿O debería simplemente cubrir los casos realmente, realmente comunes y obvios e ignorar todo lo demás?

Eli Courtwright
fuente

Respuestas:

87

Depende de las operaciones que se produzcan sobre la mesa.

Si hay muchos SELECT y muy pocos cambios, indexe todo lo que quiera ... estos (potencialmente) acelerarán las declaraciones SELECT.

Si la tabla se ve muy afectada por ACTUALIZACIONES, INSERTOS + ELIMINACIONES ... estos serán muy lentos con muchos índices, ya que todos deben modificarse cada vez que se realiza una de estas operaciones

Habiendo dicho eso, claramente puede agregar una gran cantidad de índices inútiles a una tabla que no hará nada. Agregar índices B-Tree a una columna con 2 valores distintos no tendrá sentido ya que no agrega nada en términos de buscar los datos. Cuanto más exclusivos sean los valores de una columna, más se beneficiará de un índice.

cagcowboy
fuente
1
Solo para aclarar, el índice de 2 valores podría no ser inútil en un caso específico, cuando un valor ocurre raramente y desea buscarlo. Así que no se trata de cuán únicos son los valores, se trata de cuán selectivo es el índice.
charlie_pl
44

Normalmente procedo así.

  1. Obtenga un registro de las consultas reales ejecutadas en los datos en un día típico.
  2. Agregue índices para que las consultas más importantes lleguen a los índices en su plan de ejecución.
  3. Intente evitar los campos de indexación que tienen muchas actualizaciones o inserciones
  4. Después de algunos índices, obtenga un nuevo registro y repita.

Como con cualquier optimización, me detengo cuando se alcanza el rendimiento solicitado (esto obviamente implica que el punto 0. estaría obteniendo requisitos de rendimiento específicos).

Sklivvz
fuente
26

Todos los demás te han dado buenos consejos. Tengo una sugerencia adicional para ti a medida que avanzas. En algún momento tienes que tomar una decisión sobre tu mejor estrategia de indexación. Sin embargo, al final, la mejor estrategia de indexación PLANIFICADA puede terminar creando índices que no terminan siendo utilizados. Una estrategia que le permite encontrar índices que no se utilizan es monitorear el uso de índices. Haz esto de la siguiente manera: -

alter index my_index_name monitoring usage;

Luego, puede monitorear si el índice se usa o no desde ese punto en adelante consultando v $ object_usage. Puede encontrar información sobre esto en la Guía del administrador de la base de datos de Oracle® .

Solo recuerde que si tiene una estrategia de almacenamiento de eliminar índices antes de actualizar una tabla y luego volver a crearlos, tendrá que configurar el índice para monitorear nuevamente y perderá cualquier historial de monitoreo para ese índice.

Mike McAllister
fuente
14

En el almacenamiento de datos es muy común tener una gran cantidad de índices. He trabajado con tablas de hechos que tienen doscientas columnas y 190 de ellas indexadas.

Aunque hay una sobrecarga para esto, debe entenderse en el contexto que en un almacén de datos generalmente solo insertamos una fila una vez, nunca la actualizamos, pero luego puede participar en miles de consultas SELECT que podrían beneficiarse de la indexación en cualquiera de las columnas.

Para una máxima flexibilidad, un almacén de datos generalmente usa índices de mapa de bits de una sola columna, excepto en columnas de cardinalidad alta, donde se pueden usar índices de árbol b (comprimidos).

La sobrecarga del mantenimiento del índice se asocia principalmente con el gasto de escribir en una gran cantidad de bloques y el bloque se divide a medida que se agregan nuevas filas con valores que están "en el medio" de los rangos de valores existentes para esa columna. Esto se puede mitigar particionando y alineando las nuevas cargas de datos con el esquema de partición, y utilizando inserciones de ruta directa.

Para abordar su pregunta de manera más directa, creo que probablemente esté bien indexar lo obvio al principio, pero no tenga miedo de agregar más índices si las consultas en la tabla se beneficiarían.

David Aldridge
fuente
¿Tantos en un hecho? Habría adivinado que estabas a punto de decir dimensión. Ese es un caso de uso bastante extraño. Pero, eres un DBA genial, así que voy a decir que obviamente me estoy perdiendo algo.
Stephanie Page
@ Stephanie, tenemos el mismo escenario. David ha mencionado que son índices de mapa de bits. También usamos índices BITMAP JOIN. Sí, sobre hechos. Oracle puede realizar operaciones AND muy eficientes en índices de mapa de bits. Por ejemplo, podría tener una cláusula WHERE con 5 atributos de cardinalidad baja, cada uno de los cuales tiene un índice de mapa de bits. Si observa el plan de ejecución, tendría un mapa de bits Y operaciones (básicamente un mapa de bits y una operación eficientes), luego, en el plan de ejecución, verá la conversión de mapa de bits a filas. Es muy rapido.
Tagar
12

En una paráfrasis de Einstein sobre la simplicidad, agregue tantos índices como necesite y no más.

Sin embargo, en serio, cada índice que agrega requiere mantenimiento siempre que se agregan datos a la tabla. En las tablas que son principalmente de solo lectura, muchos índices son algo bueno. En tablas muy dinámicas, menos es mejor.

Mi consejo es cubrir los casos comunes y obvios y luego, cuando encuentre problemas en los que necesite más velocidad para obtener datos de tablas específicas, evalúe y agregue índices en ese punto.

Además, es una buena idea volver a evaluar sus esquemas de indexación cada pocos meses, solo para ver si hay algo nuevo que necesite indexarse ​​o algún índice que haya creado que no se esté utilizando para nada y que deba eliminarse. .

Josef
fuente
1
Estoy de acuerdo con la reevaluación. Una buena administración nunca es una tarea de "configúrelo y olvídese". Cambios de software. Los requisitos cambian. Cambios de uso. Una nueva funcionalidad aparentemente trivial introducida un día puede convertirse rápidamente en su mayor cuello de botella, y el código básico básico de ayer puede convertirse en una grasa inactiva e innecesaria que simplemente merodea consumiendo recursos. También estoy de acuerdo con un enfoque iterativo. Si hace demasiado a la vez, no sabrá qué funcionó.
durette
6

Además de los puntos que todos los demás han planteado, el Optimizador basado en costos incurre en un costo al crear un plan para una declaración SQL si hay más índices porque hay más combinaciones para considerar. Puede reducir esto utilizando correctamente las variables de vinculación para que las sentencias de SQL permanezcan en la caché de SQL. Luego, Oracle puede realizar un análisis suave y reutilizar el plan que encontró la última vez.

Como siempre, nada es sencillo. Si hay columnas sesgadas e histogramas involucrados, esto puede ser una mala idea.

En nuestras aplicaciones web tendemos a limitar las combinaciones de búsquedas que permitimos. De lo contrario, tendría que probar literalmente cada combinación de rendimiento para asegurarse de no tener un problema al acecho que alguien encontrará algún día. También hemos implementado límites de recursos para evitar que esto cause problemas en otras partes de la aplicación si algo sale mal.

WW.
fuente
Voté a favor, pero ... diría que el tiempo de análisis adicional, si bien es interesante y académico, nunca influirá en mi elección del número correcto de índices. ¿de acuerdo?
Stephanie Page
@StephaniePage No he hecho un experimento para probar nada. Sin embargo, vi un proyecto que creó ingenuamente un índice de una sola columna en cada columna. Si algunas tablas tienen 80 columnas, supongo que podría empezar a tener un impacto. Oracle parece considerar el costo de acceso por cada índice. Pero sí, estoy de acuerdo, hay cosas más importantes a considerar que esto.
WW.
Mmm ... creo que hay una cantidad máxima de tiempo que Oracle gastará en un análisis duro ... considere un SQL con más de unas pocas tablas, digamos 7 u 8, la elección del orden de unión por sí sola podría generar cientos de posibles caminos de acceso.
Stephanie Page
6

Hice algunas pruebas simples en mi proyecto real y en la base de datos MySql real. Ya respondí en este tema: ¿Cuál es el costo de indexar múltiples columnas db?

Pero creo que será mejor si lo cito aquí:

Hice algunas pruebas simples usando mi proyecto real y la base de datos MySql real.

Mis resultados son: agregar índice promedio (1-3 columnas en un índice) a una tabla: hace que las inserciones sean más lentas en un 2.1%. Entonces, si agrega 20 índices, sus inserciones serán más lentas en un 40-50%. Pero sus selecciones serán de 10 a 100 veces más rápidas.

Entonces, ¿está bien agregar muchos índices? - Depende :) Te di mis resultados - ¡Tú decides!

codificador nocturno
fuente
Esto no debe tomarse como una profecía sin todos los detalles. Especialmente porque no se puede multiplicar la ganancia / pérdida de rendimiento de una acción a otra. La base sigue siendo la misma: agregue más índices y sus inserciones eventualmente serán más lentas debido a la recreación del índice.
SovietFrontier
3

En última instancia, la cantidad de índices que necesita depende del comportamiento de sus aplicaciones que se encuentran en la parte superior de su servidor de base de datos.

En general, cuanto más inserta, más dolorosos se vuelven sus índices. Cada vez que realiza una inserción, todos los índices que incluyen esa tabla deben actualizarse.

Ahora, si su aplicación tiene una cantidad decente de lectura, o incluso más si es casi toda lectura, entonces los índices son el camino a seguir, ya que habrá importantes mejoras de rendimiento por muy poco costo.

Orion Adrian
fuente
3

En mi opinión, no hay una respuesta estática, este tipo de cosas se incluyen en 'ajuste de rendimiento'.

Podría ser que todo lo que hace su aplicación se busque mediante una clave principal, o podría ser lo contrario, ya que las consultas se realizan sobre combinaciones de campos sin restricciones y cualquiera en particular podría usarse en cualquier momento dado.

Más allá de la indexación, hay una reogranización de su base de datos para incluir campos de búsqueda calculados, tablas de división, etc., realmente depende de sus formas de carga y parámetros de consulta, cuántos / qué datos 'realmente' deben ser recuperados por una consulta.

Si toda su base de datos está encabezada por fachadas de procedimientos almacenados, el giro se vuelve un poco más fácil, ya que no tiene que preocuparse por cada consulta ad-hoc. O puede tener una comprensión profunda del tipo de consultas que afectarán a su base de datos y puede limitar la sintonía a ellas.

Para SQL Server, el asesor de optimización del motor de base de datos me resultó útil: configura cargas de trabajo 'típicas' y puede hacer recomendaciones sobre cómo agregar / eliminar índices y estadísticas. Estoy seguro de que otras bases de datos tienen herramientas similares, ya sean "oficiales" o de terceros.

scotta
fuente
3

Esta es realmente una pregunta más teórica que práctica. El impacto de los índices en su rendimiento depende del hardware que tenga, la versión de Oracle, los tipos de índice, etc. Ayer escuché que Oracle anunció un almacenamiento dedicado, fabricado por HP, que se supone que funciona 10 veces más rápido con una base de datos 11g. En cuanto a su caso, puede haber varias soluciones: 1. Tener una gran cantidad de índices (> 20) y reconstruirlos diariamente (todas las noches). Esto sería especialmente útil si la tabla recibe miles de actualizaciones / eliminaciones diariamente. 2. Divida su tabla (si aplica su modelo de datos). 3. Use una tabla separada para datos nuevos / actualizados y ejecute un proceso nocturno que combine los datos. Esto requeriría un cambio en la lógica de su aplicación. 4. Cambie a IOT (tabla organizada por índice), si sus datos lo admiten.

Por supuesto, podría haber muchas más soluciones para tal caso. Mi primera sugerencia para ti sería clonar la base de datos en un entorno de desarrollo y ejecutar algunas pruebas de estrés en ella.

Moshe
fuente
No entiendo cómo ayudaría la reconstrucción de los índices, o cómo ayudaría un IOT.
David Aldridge
IOT: si es posible rediseñar la aplicación, de modo que se utilice un nuevo tipo de datos definido por el usuario, IOT ahorraría los gastos generales relacionados con la indexación de la tabla. este podría no ser el caso aquí. realmente depende. reconstruir el índice, en caso de que haya muchos índices y los datos nuevos no estén indexados.
Moshe
Un IOT sigue siendo una estructura de índice, con más gastos generales en las divisiones de bloques que un índice normal. "reconstruir el índice, en caso de que haya muchos índices y los datos nuevos no estén indexados" ... ¿de qué RDBMS está hablando que no mantiene los índices automáticamente para las nuevas entradas?
David Aldridge
David, tienes razón, por supuesto. Combiné eso con la capacidad de SQL Server para indexar la búsqueda de texto completo solo por demanda. Ojalá Oracle lo tuviera, ya que podría ser útil en este caso. Recomiendo seguir con las otras dos sugerencias.
Moshe
2

Si realiza principalmente lecturas (y pocas actualizaciones), entonces no hay razón para no indexar todo lo que necesitará indexar. Si actualiza con frecuencia, es posible que deba tener cuidado con la cantidad de índices que tiene. No hay un número fijo, pero notará cuando las cosas comiencen a ralentizarse. Asegúrese de que su índice agrupado sea el que tenga más sentido según los datos.

Bob King
fuente
2

Una cosa que puede considerar es crear índices para apuntar a una combinación estándar de búsquedas. Si la columna1 se busca comúnmente, y la columna2 se usa a menudo con ella, y la columna3 se usa a veces con la columna2 y la columna1, entonces se puede usar un índice en la columna1, la columna2 y la columna3 en ese orden para cualquiera de esas tres circunstancias, aunque es solo un índice que debe mantenerse.

Jeffrey L. Whitledge
fuente
2

Un índice impone un costo cuando se actualiza la tabla subyacente. Un índice proporciona un beneficio cuando se utiliza para acelerar una consulta. Para cada índice, debe equilibrar el costo con el beneficio. ¿Cuánto más lenta se ejecuta la consulta sin el índice? ¿Qué beneficio se obtiene más rápido? ¿Pueden usted o sus usuarios tolerar la baja velocidad cuando falta el índice?

¿Puede tolerar el tiempo adicional que se necesita para completar una actualización?

Necesita comparar costos y beneficios. Eso es particular a tu situación. No existe un número mágico de índices que supere el umbral de "demasiados".

También está el costo del espacio necesario para almacenar el índice, pero ha dicho que en su situación eso no es un problema. Lo mismo ocurre en la mayoría de situaciones, dado lo barato que se ha vuelto el espacio en disco.

Walter Mitty
fuente
1

Cuantas columnas hay? Siempre me han dicho que haga índices de una sola columna, no índices de varias columnas. Así que no hay más índices que la cantidad de columnas, en mi humilde opinión.

lamcro
fuente
1

Lo que realmente se reduce a esto es que no agregue un índice a menos que sepa (y esto a menudo significa recopilar estadísticas de uso) que se usará con mucha más frecuencia de lo que se actualiza.

Cualquier índice que no cumpla con esos criterios le costará más reconstruir que la penalización en el rendimiento de no tenerlo en el caso extraño de que se haya utilizado.

Torbjörn Gyllebring
fuente
1

El servidor SQL le brinda algunas buenas herramientas que le permiten ver qué índices se están utilizando realmente. Este artículo, http://www.mssqltips.com/tip.asp?tip=1239 , le brinda algunas consultas que le permiten obtener una mejor idea de cuánto se usa un índice, en lugar de cuánto se actualiza.

aboy021
fuente
0

Se basa totalmente en las columnas que se utilizan en la cláusula Where. Y como el pulgar de la regla, debemos tener índices en columnas de clave externa para evitar DEADLOCKS. El informe de AWR debe analizarse periódicamente para comprender la necesidad de los índices.

P Sharma
fuente
2
¿Índices en columnas de clave externa para evitar interbloqueos? ¿Tiene alguna referencia que explique por qué y cómo es este?
Jay Sullivan