2010-04-04 11 views
7

He leído que uno de los sacrificios para agregar índices de tabla en SQL Server es el mayor costo de insertar/actualizar/eliminar consultas para beneficiar el rendimiento de las consultas de selección.SQL Server Coste del índice

Puedo entender conceptualmente lo que sucede en el caso de una inserción porque SQL Server tiene que escribir entradas en cada índice que coincida con las nuevas filas, pero la actualización y eliminación son un poco más turbias para mí porque no puedo repase lo que el motor de la base de datos tiene que hacer.

Tomemos BORRAR como un ejemplo y asumir Tengo el siguiente esquema (perdón por el pseudo-SQL)

TABLE Foo 
col1 int 
,col2 int 
,col3 int 
,col4 int 
PRIMARY KEY (col1,col2) 

INDEX IX_1 
col3 
INCLUDE 
col4 

Ahora, si yo emita la sentencia

DELETE FROM Foo WHERE col1=12 AND col2 > 34 

entiendo lo que el motor debe hacer para actualizar la tabla (o índice agrupado si lo prefiere). El índice está configurado para facilitar la búsqueda del rango de filas que se eliminarán y para hacerlo.

Sin embargo, en este punto también necesita actualizar IX_1 y la consulta que le di no ofrece una manera obvia eficiente para que el motor de la base de datos encuentre las filas para actualizar. ¿Está obligado a hacer un escaneo de índice completo en este punto? ¿El motor lee primero las filas del índice agrupado y genera una eliminación interna más inteligente frente al índice?

Me puede ayudar a entender esto si entendiera mejor lo que está sucediendo bajo el capó, pero supongo que mi verdadera pregunta es esta. Tengo una base de datos que está gastando una cantidad significativa de tiempo en eliminar y estoy tratando de averiguar qué puedo hacer al respecto.

Cuando visualizo el plan de ejecución para la eliminación, solo muestra una entrada para "Eliminar Índice Agrupado" en la tabla Foo que enumera en la sección de detalles los otros índices que necesitan actualizarse pero no recibo ninguna indicación del costo relativo de estos otros índices.

¿Son todos iguales en este caso? ¿Hay alguna manera de estimar el impacto de eliminar uno o más de estos índices sin tener que probarlo realmente?

Respuesta

3

Índices no agrupados también store the clustered keys.
que no tiene que hacer una exploración completa, ya que:

  • la consulta va a utilizar el índice agrupado para localizar filas
  • filas contienen el otro valor de índice (c3)
  • utilizando el otro valor del índice (c3) y los valores del índice agrupado (c1, c2), puede ubicar las entradas coincidentes en el otro índice.

(Nota: No tenía problemas para interpretar los documentos, pero me imagino que IX_1 en su caso se podría definir como si también se solucionó en c1, c2 Dado que estos ya están almacenados en el índice, lo sería. tiene mucho sentido usarlos para ubicar de manera más eficiente registros, por ejemplo, actualizaciones y eliminaciones).

Todo esto, sin embargo, tiene un costo.Para cada fila a juego:

  • tiene que leer la fila, para averiguar el valor de C3
  • tiene que encontrar la entrada correspondiente (c3, c1, c2) en el índice no agrupado
  • se tiene que eliminar la entrada desde allí también.

Además, si bien la consulta rango puede ser eficiente en el índice agrupado en su caso (acceso lineal, después de encontrar un donante compatible), el mantenimiento de los otros índices muy probable que resulte en acceso aleatorio a ellos de cada fila coincidente. El acceso aleatorio tiene un costo mucho más elevado que la simple enumeración de B+ tree nodos hoja a partir de una coincidencia determinada.
Dada la consulta anterior, se gasta más tiempo en el mantenimiento del índice no agrupado: la cantidad depende en gran medida del número de registros seleccionados por el predicado col1 = 12 AND col2 > 34 .

Supongo que el costo es conceptualmente el mismo que si no tuviera un índice secundario, pero tenía, por ejemplo, una tabla separada, manteniendo (c3, c1, c2) como las únicas columnas en una clave agrupada e hizo un DELETE para cada fila coincidente usando (c3, c1, c2). Obviamente, el mantenimiento del índice es interno a SQL Server y es más rápido, pero conceptualmente, supongo que lo anterior está cerca.

Lo anterior significaría que los costos de mantenimiento de los índices se mantendrían bastante cerca el uno del otro, ya que el número de entradas en cada índice secundario es el mismo (el número de registros) y la eliminación solo puede realizarse uno a uno en cada índice.

Si necesita los índices, según el rendimiento, dependiendo de la cantidad de registros eliminados, sería mejor programar las eliminaciones, descartar los índices que no se utilizan durante la eliminación antes de eliminar y volver a agregarlos después. Dependiendo de la cantidad de registros afectados, reconstruir el indexes might be faster.

+0

Además de eso, el costo de bloqueo de cada índice. Con el fin de bloquear, cada índice es un recurso separado. –

+0

@KNoodles: de hecho, el bloqueo introduce una sobrecarga adicional. (Aunque si hay muchas operaciones de bloqueo de grano fino que se llevan a cabo, pueden ser reducidas a un solo bloqueo grande para evitar la sobrecarga para el resto de la operación.) –

Cuestiones relacionadas