2010-11-24 9 views
13

Agregar índices a menudo se sugiere aquí como un remedio para los problemas de rendimiento.Índices de base de datos: ¿Algo bueno, algo malo o una pérdida de tiempo?

(estoy hablando de leer & preguntando SOLAMENTE, todos sabemos que los índices pueden hacer que escribir sea más lento).

He intentado este remedio muchas veces, durante muchos años, tanto en DB2 como en MSSQL, y el resultado fue invariablemente decepcionante.

Mi descubrimiento ha sido que no importa cuán "obvio" fuera que un índice mejorara las cosas, resultó que el optimizador de consultas era más inteligente, y mi índice inteligentemente elegido casi siempre empeoraba las cosas.

Debo señalar que mis experiencias se refieren principalmente a las tablas pequeñas (< 100'000 filas).

¿Alguien puede proporcionar algunas pautas prácticas sobre las opciones de indexación?

La respuesta correcta sería una lista de recomendaciones algo como:

  • Nunca/Siempre indexar una tabla con menos/más de registros NNNN
  • Nunca/siempre en cuenta los índices de las teclas multi-campo
  • Nunca/índices utilice siempre agrupados
  • Nunca/siempre utilizar más de los índices de NNN en una sola tabla
  • Nunca/siempre añadir un índice cuando [alguna condición mágica me muero por conocer]

Idealmente, la respuesta dará algunos ejemplos instructivos.

+0

Todo depende de la velocidad de sus discos, y el tamaño de su memoria, y así sucesivamente. – Gabe

+2

Antes que nada, ¡edita tu pregunta! ** Agregar índices ** solo puede hacer que una consulta sea más rápida, nunca más lenta. Lo que quiere decir es que debe especificar que el optimizador de consultas ** USE ** un índice, en efecto, anula lo que haría por sí mismo ... Eso puede hacer que una consulta sea más lenta –

+3

@Charles Bretana: Agregar un índice CAN hacer una consulta más lenta si hace que el optometrista elija un plan incorrecto o si afecta negativamente el uso de otros índices. Además, agregar un índice generalmente ralentizará las inserciones/actualizaciones/eliminaciones. – sqlvogel

Respuesta

16

Los índices son algo así como la quimioterapia ... demasiado y te mata ... muy poco y mueres ... hazlo de la manera incorrecta y mueres. Debes saber cuánto, con qué frecuencia y qué tipo de cosas para que no te maten.

Su hardware, plataforma, entorno, carga, todo juega un papel. Así que para responder a sus preguntas ..

Sí, posiblemente a veces.

+8

Me encanta la analogía de la quimio (lo siento, Charlie Villanueva), pero debes agregar "pase lo que pase, te vas a sentir muy enfermo". – MusiGenesis

+0

@MusiGenesis HAHAHAH !!!! Sí, de hecho 80))) – Keng

+3

+1 De hecho, encantadora analogía, y probablemente más cerca de la realidad que la mayoría de nosotros nos gustaría – smirkingman

2
Always use clustered indexes. 

De hecho, no puede dejar de usarlos. Los datos en una tabla se presentarán en el disco en algún orden particular de todos modos, no se puede guardar como una pila o algo así. Usted tiene la oportunidad de especificar cómo exactamente se establecerán estos datos. ¿Por qué quemarlo?

Cuando tiene una tabla que agrega nuevos registros y observa que algún valor en esos registros siempre crece (como el número de pregunta de StackOverflow), cree un índice agrupado. Entonces los nuevos datos no se insertarán en el medio, sino que se agregarán básicamente a un archivo en el disco, que es una operación relativamente barata.

2

Básicamente cuando DB está recopilando datos y está vivo, los índices tienen que ir y evolucionar con ese flujo. Puede haber un índice realmente bueno en la tabla, pero después de crecer más allá de XXX registros, el mismo índice en la misma tabla es inútil y, en ese caso, debe refactorizarse.

Haber optimizado y rápido DB la única manera es controlar todo el tiempo y refactorizar el tiempo que los registros vienen en.

ejemplo de la vida real que me dieron hace algún tiempo estaba consulta súper rápido restringida por algunos rango de tiempo (created_at entre A y B) y consulta super lenta donde el rango de tiempo fue diferente. Misma consulta, misma base de datos, misma aplicación y solo una diferencia en el rango de tiempo.

+0

+1 rangos de teclas diferentes = rendimiento diferente, bueno punto. ¿Cómo se analiza/arregla esto? – smirkingman

0

Parece que está confundiendo dos conceptos aquí. índices Adición * general puede solamente hacer una consulta de lectura más rápida, muy rara vez (casi nunca) más lento. Agregar un índice nunca obliga al optimizador de consultas a usarlo. Solo lo usará si cree que puede beneficiarse de él, y generalmente es muy inteligente con respecto a esas decisiones.

Para inserciones/actualizaciones, por supuesto, cada índice perjudica el rendimiento un poco más ... Pero en el otro extremo del espectro, por ejemplo, una base de datos de solo lectura (como una base de datos de direcciones de USPS que se distribuye mensualmente) , en el uso operacional no habría inserciones/actualizaciones, por lo que el único impacto negativo de los índices adicionales es el espacio en disco que ocupan.

Esto es completamente diferente que especificando que el optimizador de consultas USE un índice, en efecto anulando lo que haría por sí mismo ... Eso puede hacer que una consulta sea más lenta.

EDIT: Editado para eliminar la posibilidad de interpretaciones erróneas por parte de lectores demasiado literales.

+1

@Charles Bretana: "solo puedo hacer una consulta más rápido, nunca más lento" No estoy de acuerdo _completamente_ y ese es precisamente el punto que estoy haciendo; agregar un índice cambia la forma en que el optimizador de consultas establece su plan (un índice se considera una sugerencia fuerte). He observado (y sincronizado) la misma consulta, que se vuelve considerablemente más lenta cuando se agrega un índice. Y por favor absténgase de sugerir lo que debería estar preguntando; el fraseo de la pregunta debería dejar en claro que sé lo que estoy buscando, gracias. – smirkingman

+0

@smirkingman, los casos extremos en los que sucede lo que describes son tan raros que no vale la pena invertir ningún esfuerzo significativo. Y el fraseo de su pregunta indica que no entiende la tecnología de índice. a saber, "... el índice mejoraría las cosas, resultó que el optimizador de consultas fue más inteligente, y mi índice inteligentemente elegido casi siempre empeora las cosas". Este estadista no puede ser literalmente cierto, excepto en circunstancias muy raras e inusuales (a menos que anule el optimizador). Si fuera cierto, implica que el resto de la industria de bases de datos son idiotas. –

+1

@Charles Bretana Lo siento, pero no son casos extremos. Su experiencia podría ser que los índices siempre mejoran las cosas, la mía no, y es precisamente este mito el que estoy cuestionando. Mi pregunta es aún más válida cuando observo que las respuestas hasta ahora carecen de cualquier justificación objetiva, excepto las visceras y/o el aprendizaje memorístico. Ah, y por cierto, he estado trabajando con DBMS desde principios de la década de 1990 y probablemente he pasado más noches estudiando planes de consulta que cenas calientes; entonces, en lugar de ser despectivo, respalde sus respuestas con algo más concreto que lo que lee en un libro. – smirkingman

10

Como regla general, las claves principales y las claves externas deben indizarse. Por lo general, la clave principal se indexa simplemente definiéndolas como tales, pero los FK no están en todas las bases de datos (definitivamente no están en SQL Server, realmente no puedo hablar de otros dbs). Los usará en uniones, por lo que generalmente es fundamental para el rendimiento definirlos.

Ahora bien, si tienen campos que utiliza a menudo en las cláusulas where, pueden beneficiarse de los índices como proporcionar así varias cosas:

  • primer lugar, el campo debe tener un rango de valores . Un campo de bit o un campo con solo 2 o 3 valores casi nunca usan un índice.

  • En segundo lugar las consultas que escriba deben ser sargables. Es decir, deben estar diseñados para usar índices. Sospecho que si nunca obtiene mejoras de rendimiento de lo que parecen candidatos probables para los índices, entonces probablemente tenga consultas que no sean sargables. Por ejemplo, tome "WHERE Name like '% Smith'" como cláusula where. Sin conocer los primeros caracteres, el optimizador no puede usar el índice.

Las tablas pequeñas rara vez se benefician mucho de los índices. Si el optimizador puede mantener todo en la memoria, a menudo es más rápido hacerlo. Si estuvieras trabajando con tablas de registros multimillonarios, verías que los índices son críticos.

La indexación puede ser muy compleja y si le interesa el tema, le sugiero que obtenga un buen libro sobre el ajuste del rendimiento de su base de datos en particular y que lea en profundidad sobre ellos.

+1

+1 para sugerencias concretas: rango/sargables/tablas pequeñas – smirkingman

1

Si se espera que una tabla sea el objetivo de una combinación, es mejor tener un índice agrupado en esa tabla para que las uniones se puedan realizar secuencialmente a través de las páginas de datos. Las columnas en el índice agrupado se incluirán (en algunos sistemas de BD) en todos los otros índices en esa tabla, ya que esos son los valores que los índices usarán para hacer referencia a los datos de la tabla.Para evitar que los demás índices sean demasiado grandes, las columnas del índice agrupado deben ser lo más angostas posible, por lo que es mejor utilizar únicamente tipos de datos numéricos en lugar de caracteres en el índice agrupado. En general, son necesarias menos columnas que más columnas, pero observe que tres columnas int (12 bytes por fila) son mucho mejores que una columna nvarchar(32) (potencialmente 64 bytes por fila).

Si el índice agrupado es estrecho, algunos índices adicionales no deberían afectar negativamente el rendimiento mucho incluso en tablas muy grandes.

2

Necesita índices. Solo con los índices puede acceder a los datos lo suficientemente rápido.

para que sea lo más corto posible:

  • añadir índices de columnas que con frecuencia son el filtrado (o agrupación) para. (por ejemplo, un estado o nombre)
  • like y las funciones sql podrían hacer que el DBMS no use índices.
  • agregar índices solo en columnas que tienen muchos valores diferentes (por ejemplo, no campos booleanos)
  • Es común agregar índices a claves externas, pero no siempre es necesario.
  • No agregue índices en tablas muy cortas
  • Nunca agregue índices cuando no sepa cómo deben mejorar el rendimiento.

Finalmente: busque en los planes de ejecución para decidir cómo optimizar las consultas.

Agregará índices solo para una única consulta crítica. En este caso, agregará exactamente los índices que se necesitan en la consulta en cuestión (índices de varias columnas).

5

Un índice que nunca se utiliza es una pérdida de espacio en disco, además de agregar tiempo de inserción/actualización/eliminación. Probablemente sea mejor definir primero el índice de agrupamiento, luego defina índices adicionales mientras se encuentra escribiendo las cláusulas WHERE.

Un error de índice común que veo es que la gente se pregunta por qué una selección en col2 (o col3) lleva tanto tiempo cuando el índice se define como col1 ASC, col2 ASC, col3 ASC. Cuando tiene un índice de columna múltiple, su cláusula WHERE debe usar la primera columna en el índice, o la primera y segunda columna en el índice, y así sucesivamente.

Si necesita acceder a los datos por col2, necesita un índice adicional que se define como col2 ASC.

Con tablas de dominio pequeñas, a veces es más rápido hacer una exploración de tabla que leer filas de la tabla usando un índice. Esto depende de la velocidad de su máquina de base de datos y de la velocidad de la red.

+0

+1 para identificar errores comunes y proponer una solución – smirkingman

Cuestiones relacionadas