2012-10-09 19 views
7

La secuencia de comandos en la que estoy trabajando está diseñada para actualizar una tabla de base de datos que registra el país de uso y el estado de todas las direcciones IP (o casi todas). Actualmente lo mantengo simple y solo estoy obteniendo datos de los 5 RIR (Registros Regionales de Internet) y guardándolos en mi base de datos.Variación en la velocidad de las inserciones SQL

Inicialmente las velocidades no eran prácticas, pero se han mejorado significativamente al reducir la cantidad de información en el registro y agrupar las inserciones SQL en grupos de 1000 y con una sola consulta. Sin embargo, cuando ejecuto el script ahora obtengo variaciones muy grandes en la velocidad de las inserciones SQL y me preguntaba si alguien sabía por qué.

Estas son algunas de las velocidades que he grabado. En la prueba, separé el tiempo necesario para ejecutar las iteraciones del script en PHP y el tiempo necesario para aplicar el enunciado sql; no he incluido los tiempos de PHP en la lista siguiente, ya que el efecto fue insignificante; no más de 1 segundo incluso para los bloques de datos más grandes.

prueba acelera (número de filas de datos que se inserta sigue siendo el mismo en toda)

Prueba 1 total SQL tiempo de ejecución: 33 segundos

de prueba 2 tiempo de ejecución total SQL: 72 segundos

Prueba 3 Tota l Tiempo de ejecución SQL: 78 segundos

Otras pruebas continuaron fluctuando entre ~ 30 segundos y ~ 80 segundos.

tengo dos preguntas:

1) ¿Debo aceptar estas disparidades como el camino del mundo, o hay una razón para ellos?

2) Me sentí nervioso por agrupar las ~ 185000 inserciones de fila en una consulta. ¿Hay alguna razón por la que deba evitar el uso de una consulta para estos insertos? No he trabajado con esta cantidad de datos que se guardan de una vez.

Gracias

__

La tabla de base de datos es el siguiente.

Sorage motor - InnoDB

Columnas:

id - int, clave primaria

registro - varchar (7)

código - varchar (2)

tipo - varchar (4)

inicio - varchar (15)

valor - int

fecha - fecha y hora

estado - VARCHAR (10)

+0

Hay una longitud máxima configurable para los comandos en MySQL: el estándar es superior a 1 MB. Con 185k filas, puede llegar a este límite. Puedes elevarlo, por supuesto, y no sé por qué no deberías. – Argeman

+0

supongo que utiliza el tipo de tabla innodb estándar? – Argeman

+0

80 segundos para una inserción, incluso 1000 filas, suena muy largo. A menudo me divierto en grupos de 100 y suceden lo suficientemente rápido ("instantáneamente") que nunca me preocupé, esperaría algo similar con 1000 filas. Factores que pueden ralentizarlo: el tráfico de red (pero no 80 segundos de trabajo), demasiados índices (una vez más, sin contar el tiempo suficiente) y activadores (¿tiene alguno?). Pero deberías estar obteniendo mucho, mucho más rápido que eso, profundizaría más. ¡Pero compare 100 contra 1000 contra 10,000 antes de que regordete para el lote! – Robbie

Respuesta

3
1) Should I accept these disparities as the way of the world, or is there a reason for them? 

variaciones en la velocidad puede ser debido a los procesos que compiten utilizando el disk-IO - por lo tanto, esperando recursos. Si este es un servidor de producción, no es un servidor de prueba solitario, entonces algunos otros procesos están solicitando acceso al disco.

2) I felt nervous about lumping the ~185000 row inserts into one query. Is there any reason I should avoid using one query for these inserts? I've not worked with this amount of data being saved at one time before. 

También debe dividir las inserciones en grupos de X insertos, e insertar cada grupo como una transacción.

La determinación del valor de X de alguna otra forma, excepto experimentalmente, es difícil.

La agrupación de inserciones en las transacciones garantiza que los datos se escriban (confirmen) en el disco solo después de cada transacción, no después de cada inserción (autocomprometida).

Esto tiene un buen efecto en disk-IO y si agrupa varias inserciones en una transacción puede tener un efecto negativo en la memoria disponible. Si la cantidad de datos no confirmados es demasiado grande para la memoria actual, el DBMS comenzará a escribir los datos en un registro interno (en el disco).

Por lo tanto, X depende de la cantidad de insertos, la cantidad de datos asociados con cada inserción, los parámetros permitidos de memoria/usuario/sesión. Y muchas otras cosas


Existen algunas herramientas geniales (gratuitas) de percona. Te ayudan a controlar la actividad de DB.

También puede mirar en vmstat reloj -n 0,5 'vmstat'

la cantidad y la variación de los datos que se escriben en el disco por las actividades del entorno de producción.

Comience su secuencia de comandos y espere hasta que note un aumento en la cantidad de bytes que se escriben en el disco. Si escribir el paso ascendente es más o menos un valor constante (por encima del uso de producción normal), se está revolucionando & intercambiando, si es rítmico, solo está escribiendo para commits.

+0

El registro binario AFAIK es una opción. De hecho, es utilizado por las configuraciones de replicación cuando utilizan técnicas de replicación binarias. –

+0

Muchas gracias. Es un servidor de producción, así que tiene sentido. Estoy contento siempre y cuando tenga una idea de por qué los resultados varían. Estaba usando grupos de 1000 inserciones por instrucción sql, pero ahora he aumentado eso a 10000 ya que los datos en cada fila son muy pequeños. Sin embargo, intentaré monitorear el uso de recursos para esto. Gracias de nuevo. – Marvin

Cuestiones relacionadas