Efecto de un índice en las declaraciones de actualización donde la columna de actualización no está en un índice

16

Constantemente veo que la gente dice que los índices se ralentizan update, deletey insert. Esto se usa como una declaración general, como si fuera un absoluto.

Mientras ajusto mi base de datos para mejorar el rendimiento, sigo encontrando esta situación que parece contradecir esa regla lógicamente para mí, y en ningún lado puedo encontrar a nadie que diga o explique de otra manera.

En SQL Server, y creo / presumo la mayoría de los otros DBMS, sus índices se crean en función de columnas específicas que especifique. Las inserciones y eliminaciones siempre afectarán a una fila completa, por lo que no hay forma de que no afecten el índice, pero las actualizaciones parecen un poco más únicas, pueden afectar específicamente solo ciertas columnas.

Si tengo columnas que no están incluidas en ningún índice y las actualizo, ¿se ralentizan solo porque tengo un índice en otras columnas de esa tabla?

Como ejemplo, digamos en mi Usertabla que tengo uno o dos índices, la clave principal que es una columna de Identidad / Incremento automático, y posiblemente otra en alguna columna de clave externa.
Si actualizo una columna sin el índice directamente en ella, como decir su número de teléfono o dirección, ¿se ralentiza esta actualización porque tengo índices en esta tabla en otras columnas en cualquier situación? Las columnas que estoy actualizando no están en índices, por lo que lógicamente, los índices no deberían actualizarse, ¿no? En todo caso, creo que se aceleran si uso los índices en la cláusula WHERE.

Ryan
fuente
so there is no way they will not affect the indexa excepción de los índices filtrados ...
usr
Pienso en el índice no cubierto y no agrupado como que contiene punteros a registros (generalmente en los nodos de hoja de índice agrupados de la tabla). Creo que una situación que causa una desaceleración durante una ACTUALIZACIÓN (de un atributo no incluido) podría ser una situación en la que la ACTUALIZACIÓN provocó que el registro se moviera dentro del índice agrupado. Todavía no estoy seguro de si un movimiento haría que el puntero cambiara, O si el puntero es simplemente un valor CLAVE en el índice agrupado, en cuyo caso la posible actualización de ubicación no importaría porque el sistema solo haría una búsqueda CLAVE para obtener el valor récord.
Jmoney38

Respuestas:

6

Tiene razón en que actualizar una columna no indexada no causará cambios en los índices. En un caso simple, tampoco habría un impacto general sobre la mesa.

Si una consulta puede usar el Índice para buscar datos, puede acelerar la búsqueda, pero el comportamiento exacto (dependiendo de su marca SQL) puede diferir de otras marcas de SQL. (Yo uso principalmente Microsoft SQL Server).

Por supuesto, actualizar una columna con un volumen de datos significativamente mayor podría causar cierto movimiento de las filas a diferentes páginas, etc.

RLF
fuente
1
SQL Server se menciona en el OP, agregué una etiqueta, así que creo que puede asumir SQL Server
Tom V - Team Monica
10

Para un sistema moderno relativamente rápido, la adición de un índice único a una tabla OLTP probablemente será prácticamente indetectable desde el punto de vista del rendimiento para la gran mayoría de los sistemas . Dicho esto, no debe crear índices innecesarios, y probablemente no debería crear índices de una sola columna para cada columna de una tabla.

Está en lo cierto al suponer que, para muchas consultas, la presencia de índices útiles dará como resultado una mejora de velocidad muy notable.

Aunque su pregunta parece estar relacionada con el rendimiento, existen otros problemas potenciales relacionados con la adición de índices, que incluyen, entre otros:

  1. El tiempo requerido para crear el índice puede resultar en bloqueo mientras el índice se agrega a la tabla. La cerradura tiene una vida muy corta, y lo más probable es que no cree un gran problema.

  2. Los cambios de índice dan como resultado que los planes de ejecución se invaliden para cualquier plan que haga referencia a la tabla subyacente. Cuando esos planes de ejecución se vuelven a compilar, el rendimiento puede cambiar negativamente para algunas consultas.

  3. Las modificaciones de índice pueden dar lugar a consultas que devuelven errores donde no se devolvió ninguno anteriormente. Tomemos el caso de un índice filtrado que se utilizó para devolver fechas contenidas en un campo varchar; si el filtro eliminó las filas que no eran fechas, y ese filtro se modifica posteriormente, las consultas que se basaron en ese índice ahora pueden fallar al intentar convertir datos que no son de fecha.

  4. Un nuevo índice puede hacer que cambie el orden de ejecución, dando lugar a posibles puntos muertos que no se produjeron antes.

Max Vernon
fuente
"La ruta de código requerida para una actualización cuando el índice no se verá afectado aún debe evaluarse" esto no es cierto. La fase de compilación / optimización sabrá muy bien qué índices deben actualizarse, si los hay, y creará el plan en consecuencia. Una instrucción UPDATE que no modifique (declare en la lista SET) columnas en un índice (incluidas las columnas INCLUDE y clave agrupada) no tendrá que actualizar ese índice, y la fase de ejecución ni siquiera lo tocará. ELIMINAR e INSERTAR obviamente toca todas las columnas (lógicamente) y tiene que actualizar todos los índices.
Remus Rusanu
@RemusRusanu, pero ¿no será necesario evaluarlo si el índice podría usarse para ubicar las filas que deben actualizarse?
Tom V - Equipo Mónica
@RemusRusanu: supongo que una vez que QO ha compilado un plan, no se necesita más CPU; sin embargo, para compilar el plan, ciertamente debe hacerlo. Si los planes se compilan con frecuencia, puede haber una pequeña diferencia.
Max Vernon el
@TomV que usa el índice para ubicar las filas candidatas para eliminar / actualizar es un tema completamente diferente. Si ese es el caso, las ventajas de localizar las filas a través de un índice deberían abrumar cualquier problema de costo de mantenimiento del índice.
Remus Rusanu
@MaxVernon Yo diría que no existe un escenario válido de recompilaciones frecuentes de DML (ACTUALIZACIÓN). Compro algunos casos para recompilaciones válidas (¿inevitables?) Para consultas ad-hoc. ¿Pero DML? ¿Qué tipo de aplicación podría crear declaraciones de ACTUALIZACIÓN únicas y ad-hoc? Recopilaciones frecuentes con DML gritan en voz alta "Parameterize me".
Remus Rusanu
-2

Si la operación de actualización apunta a una columna no indexada de tamaño fijo (como un entero), en general no debería ser lenta, pero en comparación con una instrucción select, la actualización también debe escribirse en el disco lento.

Sorin
fuente