2011-02-17 15 views
7

Actualmente estoy tomando el curso "Evaluación de desempeño" en la universidad, y ahora estamos haciendo una tarea en la que estamos probando el uso de la CPU en un servidor de base de datos PHP y MySQL. Usamos httperf para crear tráfico personalizado y vmstat para rastrear la carga del servidor. Estamos ejecutando 3000 conexiones al servidor PHP, tanto para INSERTAR como para ELIMINAR (ejecutar por separado).MySQL: ¿Por qué ELIMINAR consume más CPU que INSERTAR?

Los números muestran que la operación DELETE consume mucha más CPU que INSERT, y me pregunto por qué.

Inicialmente pensé que INSERT requería más uso de CPU, ya que los índices tendrían que ser recreados, los datos necesarios para ser escritos en el disco, etc. Pero obviamente estoy equivocado, y me pregunto si alguien me puede decir la técnica razón por esto

+0

Pregunta obvia: ¿Es * siempre * por lo que un DELETE requiere más recursos que un INSERT, o podría ser solo su configuración específica? Si siempre es así, ¿quién dice eso? – Tomalak

Respuesta

3

DELETE también requiere la escritura de datos en el disco, además del recálculo de los índices, y además, un conjunto de comparaciones lógicas para encontrar los registros que está intentando eliminar en primer lugar.

+2

Este argumento depende mucho de las restricciones en la base de datos y de si los datos que se insertan podrían verse afectados por esas restricciones. –

1

Eliminar requiere más lógica de la que crees; cuánto depende de la estructura del esquema.

En casi todos los casos, al eliminar un registro, el servidor debe verificar las dependencias de ese registro como una referencia de clave externa. Eso, en pocas palabras, es una consulta de las tablas del sistema en busca de definiciones de tabla con una referencia de clave externa a esta tabla, luego una selección de cada una de esas tablas para los registros que hacen referencia al registro que se eliminará. Allí mismo, ha aumentado el tiempo de cálculo en un par de órdenes de magnitud, independientemente de si el servidor realiza eliminaciones en cascada o simplemente devuelve un error.

Las estructuras internas de datos autoequilibradas también deberían reorganizarse, y los índices tendrían que actualizarse para eliminar las ramas ahora vacías de los árboles de índice, pero estos tendrían contrapartidas en las operaciones Insertar.

+1

Si no hay una clave externa (saliente) registrada para esa tabla, no hay trabajo adicional. Si hay una clave externa (entrante), hay tanto trabajo para una inserción. El argumento de las claves externas no es lo suficientemente fuerte en mi humilde opinión. – Tomalak

+1

No estoy de acuerdo. Si no hay una clave externa que haga referencia a esta tabla en otro lugar, igual debe verificarlo con una exploración de tabla de sysobjects (o lo que sea) antes de eliminar el registro. No es así al insertar. Si el registro hace referencia a una tabla extranjera, una inserción ES más costosa, pero no mucho; debe encontrar el registro con el ID al que se hace referencia en la tabla a la que se hace referencia. La tabla a la que se hace referencia es estáticamente conocida o se descubre con una búsqueda de tiempo de registro en sysobjects (et alii) para extraer la definición de la tabla actual. Encontrar cero o uno registros con la ID referenciada también es tiempo de registro. – KeithS

+1

Suponiendo que tiene que verificar con una * consulta separada * para claves externas con cada solicitud de eliminación (lo cual me niego a creer, ya que es una cosa tan obvia para optimizar para eso probablemente lo hicieron) - todavía * * tiene que hacer lo mismo para cada inserción. Suponiendo además que no hay FK en ninguna dirección, entonces una eliminación no es semánticamente diferente de una inserción. Una inserción incluso requiere bytes reales escritos en el disco, incluso una división de índice tal vez, pero una eliminación, nada de eso. * Si * elimina son generalmente más lentos (FK aparte), me gustaría saber por qué. – Tomalak

5

Al menos con InnoDB (y espero que te tengan en esto), tienes más operaciones incluso sin claves externas. Un inserto es aproximadamente la siguiente:

  1. Insertar fila
  2. Marcos en tampón registro binario
  3. Marcos cometer

deleciones hacer lo siguiente:

  1. Marcos fila eliminado (tomando la El mismo golpe que una inserción - la página se reescribe)
  2. Marca en el búfer de registro binario er
  3. marca comprometida
  4. En realidad vaya a eliminar la fila, (teniendo el mismo éxito como una inserción - página se reescribe)
  5. hilo Purga rastrea deleciones en búfer de registro binario también.

Para eso, tienes dos veces más trabajo para eliminar que insertar. Una eliminación requiere esas dos escrituras porque debe estar marcada como eliminada para todas las versiones en el futuro, pero solo se puede eliminar cuando no quedan transacciones que la puedan ver. Debido a que InnoDB solo escribe bloques completos, en el disco, la penalización de modificación para un bloque es constante.

Cuestiones relacionadas