2009-06-22 2 views
7

Hipotéticamente, en una base de datos SQL Server, si tengo una tabla con dos campos int (por ejemplo, una relación muchos a muchos) que participa en uniones entre otras dos tablas, ¿en qué tamaño aproximado la tabla se vuelve lo suficientemente grande donde el beneficio de rendimiento de los índices en los dos campos int supera la sobrecarga impuesta por dichos índices?¿Cuándo una tabla de base de datos crece lo suficiente como para que un índice sea beneficioso?

¿Existen diferencias en la arquitectura entre las diferentes versiones de SQL Server que cambiarían sustancialmente esta respuesta?

Respuesta

10

Para las consultas que involucran pequeñas porciones de las filas de la tabla, los índices siempre son beneficiosos, ya sea 100 filas o 1,000,000.

Ver esta entrada en mi blog para ejemplos con los planes y detalles de rendimiento:

Las consultas como esta:

SELECT * 
FROM table1 t1 
JOIN table2 t2 
ON  t2.col = t1.col 

muy probablemente utilizará HASH JOIN. Se generará una tabla hash para la tabla más pequeña, y las filas de la tabla más grande se usarán para sondear la tabla hash.

Para hacer esto, no se necesita ningún índice.

Sin embargo, esta consulta:

SELECT * 
FROM table1 t1 
JOIN table2 t2 
ON  t2.col = t1.col 
WHERE t1.othercol = @value 

utilizará NESTED LOOPS: las filas de la tabla exterior (table1) será buscado utilizando un índice en table1.othercol, y las filas de la tabla interna (table2) será buscado utilizando un índice en table2.col.

Si no tiene un índice en col1, se usará un HASH JOIN que requiere escanear todas las filas de ambas tablas y algunos recursos adicionales para construir una tabla hash.

índices también son útiles para las consultas como esta:

SELECT t2.col 
FROM table1 t1 
JOIN table2 t2 
ON  t2.col = t1.col 

, en cuyo caso el motor no necesita leer table2 sí en absoluto: eveything que necesita para esta consulta se puede encontrar en el índice , que puede ser mucho más pequeño que la tabla en sí y más eficiente de leer.

Y, por supuesto, si es necesario ordenar los datos y tienen índices en tanto table1.col y table2.col, a continuación, la siguiente consulta:

SELECT * 
FROM table1 t1 
JOIN table2 t2 
ON  t2.col = t1.col 
ORDER BY 
     t2.col 

probablemente utilizará MERGE JOIN método, que es súper rápido si ambos conjuntos de filas de entrada están ordenados y su salida también está ordenada, lo que significa que ORDER BY es gratuito.

Tenga en cuenta que incluso si no tiene un índice, un optimizador puede elegir Eager Spool su tabla pequeña, lo que significa crear un índice temporal para la duración de la consulta y descartar el índice una vez que finalice la consulta.

Si la consulta es pequeña, será muy rápido, pero de nuevo, un índice no dolerá (para las consultas de SELECT, me refiero). Si el optimizador no lo necesita, simplemente no se usará.

Tenga en cuenta, sin embargo, que la creación de un índice puede afectar el rendimiento DML, pero es otra historia.

+0

En realidad, la base de datos no ordena las claves en una sola página. Hasta que llegue más allá de ese punto, no hay beneficio. Y probablemente por varias páginas más allá de eso. – dkretz

+0

@Robert: también se benefician cuando usa solo las columnas indexadas en la consulta o cuando necesita ordenar los datos. Y no, no siempre son un beneficio en la cláusula WHERE, solo en las muy selectivas. – Quassnoi

+0

Quassnoi, vi tu publicación en el blog. Para que lo sepas, la decisión final de indexar nuestra base de datos (basada en información adicional en esta publicación: stackoverflow.com/questions/1033796/...) fue indexar todas las claves externas EXCEPTO las que participan en combinaciones de tablas de búsqueda que contienen MENOS DE 10 ARCHIVOS. –

0

Creo que tan pronto como comiences a hacer uniones en esos campos int, tu mesa es lo suficientemente grande. Si la tabla es lo suficientemente pequeña como para que no se beneficie de un índice, entonces la sobrecarga no sería lo suficientemente significativa como para que desee cancelarla.

Cuando pienso en la sobrecarga debido a un índice, generalmente considero la frecuencia con la que el índice de la tabla cambiará, insertando, eliminando y actualizando las columnas indexadas.

+0

Los índices agregan sobrecarga en las sentencias SELECT también, no solo INSERTES y ACTUALIZACIONES. –

1

El índice casi siempre aumentará el rendimiento de la consulta, a costa de una memoria extra y un costo de rendimiento para inserción/eliminación (ya que necesita mantener el índice en ese punto). La creación de perfiles será la única forma definitiva de determinar si el índice, en su caso particular, es beneficioso o no.

En general, cambia la memoria de velocidad cuando crea un índice (que no sea el costo adicional de inserción). Si realiza muchas consultas (selecciones o actualizaciones) en relación con la cantidad de filas insertadas/eliminadas, los índices casi siempre aumentarán su rendimiento.

+0

Si el caso es relativamente estándar (como en el ejemplo de dos entradas en una tabla), el punto de vuelco es relativamente uniforme, o variará en función del número de columnas adicionales en las tablas externas, y otras funciones desconocidas factores? –

+0

El optimizador sabe dónde está el punto de inflexión, por lo que no tiene que preocuparse por ello. Si la penalización de carga es significativa porque estás cargando filas lo suficientemente rápido como para notarla, alcanzarás ese punto en un instante. – dkretz

+0

La indexación acelerará sus consultas, casi en todos los ámbitos. El número de columnas hará poca diferencia, ya que es una cuestión de ubicar las filas apropiadas para devolver (que es algo separado del número de columnas). Si tiene muy pocos datos, es posible que el índice no ayude demasiado, pero también es casi gratuito. Personalmente siempre indexo las columnas que usaré con frecuencia para cualquier consulta de ubicación (incluidas las filas de actualización [siempre que no cambie el columna indexada), ya que será mucho más rápido con un índice, incluso en casos relativamente pequeños. –

1

depende de la selectividad de sus datos, si sus datos no son lo suficientemente selectivos, entonces el índice podría no ser utilizado ya que el costo sería demasiado caro. Si solo tiene 2 valores en la tabla y estos valores están distribuidos uniformemente obtendrá un escaneo no una búsqueda

Sigo creyendo que cada tabla debe tener una clave principal, si la tiene, también tiene un índice

+0

Es verdad que en mi hipotético (una unión de muchos a muchos) las tablas externas ya tendrían índices. –

+0

¿Una mesa de unión de dos columnas? Sería altamente inusual tener baja selectividad en claves primarias de otras dos tablas. – dkretz

+0

@Robert: ¿qué hay de tu tabla de enlaces? También debe tener una clave principal, si no otra cosa, una clave primaria compuesta en las dos columnas de clave externa. ¿Cómo lo protege su esquema actual de los registros duplicados? – GalacticCowboy

1

La penalización por la inserción será insignificante hasta mucho después de que aparezca el beneficio de los índices. El optimizador es lo suficientemente inteligente como para ignorar los índices de todos modos hasta que ese punto haga clic. Así que solo indexe la tabla desde el principio.

+0

¿Está diciendo que SQL Server creará un plan de ejecución utilizando los índices solo si determina que el índice proporcionará un beneficio? –

+1

Derecha. Ha habido varias preguntas en SO sobre por qué los índices no se están utilizando en tablas pequeñas, y la respuesta ha sido "todavía no tienes suficientes datos". – dkretz

+0

Así que mi pregunta se transforma en "¿A qué número de registros el optimizador de SQL Server patea el índice?" Y la respuesta es: "¿No te importa?" –

1

Otra cosa a tener en cuenta es el concepto de rendimiento de codificación: a veces tener un índice puede simplificar la carga mental de pensar cómo gestionar la relación entre diferentes datos. a veces puede complicarlo ...

+0

Una cosa que no mencioné es que uso Linq a SQL, que parece tomar los nombres de campo y los índices como señales de lo que se incluye en el modelo; específicamente, las combinaciones de claves extranjeras obtienen una preferencia especial. –

1

Independientemente del tamaño, siempre hay un beneficio de rendimiento al usar un índice cuando se realiza una búsqueda.

En lo que respecta a los gastos generales, la pregunta es: ¿qué gastos generales significa y cómo se relaciona con el valor de una búsqueda? Los dos son valores separados, después de todo.

Hay dos formas de sobrecarga para un índice: espacio (que normalmente es insignificante, según cómo esté estructurado el índice) y vuelva a indexar en la inserción (el servidor debe recalcular un índice después de cada inserción).

Como mencioné, el problema del espacio probablemente no sea tan importante. Pero volver a indexar es. Afortunadamente, debe realizar muchas inserciones casi continuas antes de que esa forma de sobrecarga se convierta en un problema.

Así que, en conclusión: casi siempre es mejor tener un índice. Comience desde esa posición y espere hasta que la nueva indexación se convierta en un cuello de botella. Entonces puedes buscar alternativas.

+0

Incorrecto. Cree una tabla con solo una fila, agregue un índice y compruébelo usted mismo. –

+0

Ok, por "independientemente del tamaño" me refiero a "para tablas con un recuento de filas mayor que 3". ¿Mejor? – Randolpho

+0

¿Es el tirón realmente tres registros? Eso no parece probable. –

1

Lo mejor es dejar que el propio servidor averiguarlo. Usted crea un índice en las columnas donde tiene sentido (estoy seguro de que hay capítulos completos, si no hay libros sobre cómo hacer esto de la mejor manera), y deja que el servidor SQL averigüe cuándo/cómo usar el índice.

En muchos casos, al optimizar, necesitará leer los documentos de su DBMS particular para obtener más información sobre cómo utiliza los índices y relacionarlos con las consultas que utiliza la aplicación que está optimizando. Entonces puede ajustar el uso del índice.

Cuestiones relacionadas