2009-11-23 59 views
12

He estado luchando con un problema que solo ocurre cuando la base de datos ha estado inactiva durante un período de tiempo para los datos consultados. La primera consulta será extremadamente lenta, del orden de 30 segundos y luego las consultas relacionadas serán tan rápidas como 0.1 segundos. Supongo que esto está relacionado con el almacenamiento en caché, pero no he podido encontrar la causa.mysql lento en la primera consulta, luego rápido para consultas relacionadas

Cambiando las variables mysql tmp_table_size, max_heap_table_size a un tamaño más grande no tuvo ningún efecto excepto para crear las tablas temporales en la memoria.

No creo que esto esté relacionado con la consulta en sí, ya que está bien indexado y después de la primera consulta lenta, las variantes de la misma consulta no aparecen en el registro lento de consultas. Estoy más interesado en tratar de determinar la causa de esto o una forma de restablecer el caché ofensivo para que pueda solucionar el problema.

+3

No soy experto en MySQL, pero probablemente debería agregar la versión de MySQL, la Información del sistema operativo y la información del motor (MyISAM, InnoDB?) –

+0

buena sugerencia, 5.0.26-estándar-registro y sobre todo InnoDB.
Linux 2.4.21-47.ELsmp # 1 SMP Wed Jul 5 20:30:30 EDT 2006 x86_64 x86_64 x86_64 GNU/Linu –

+0

Esto pertenece a http://www.serverfault.com –

Respuesta

7

Las páginas de los archivos de datos innodb se almacenan en caché en el grupo de búferes innodb. Esto es lo que esperarías. Leer archivos es lento, incluso en discos duros buenos, especialmente lecturas aleatorias, que es principalmente lo que ven las bases de datos.

Puede ser que su primera consulta esté realizando algún tipo de escaneo de tabla que atrae muchas páginas al grupo de búferes, y luego acceder a ellas es rápido. O algo similar.

Esto es lo que esperaría.

Idealmente, utilice el mismo motor para todas las tablas (excepciones: tablas del sistema, tablas temporales (tal vez) y tablas muy pequeñas o de corta duración). Si no haces esto, entonces tienen que luchar por el carnero.

Suponiendo que todas sus tablas son innodb, haga que la agrupación de almacenamientos intermedios use hasta el 75% de la ram física del servidor (suponiendo que no ejecute demasiadas tareas en la máquina). Luego podrá acomodar alrededor de 12G de su base de datos en RAM, así que una vez que esté "calentado", el 12G "más usado" de su base de datos estará en ram, donde accederá es agradable y rápido.

Algunos usuarios de mysql tienden a "calentar" los servidores de producción después de un reinicio enviándoles consultas copiadas desde otra máquina por un tiempo (estos serán esclavos de replicación) hasta que los agreguen a su grupo de producción. Esto evita la extrema lentitud que se observa cuando el caché está frío. Por ejemplo, Youtube hace esto (o al menos solía hacerlo; Google los compró y ahora pueden usar Google-fu)

+0

, la respuesta resultó ser cambiar el archivo de configuración mysql y sintonizar innodb. Con un aumento en el tamaño de las variables innodb, la base de datos ahora se calienta después de algunas consultas. Supongo que lo que sucedía era que el caché era demasiado pequeño para tener todos los índices de la tabla en la memoria, por lo que se cambiaba constantemente del disco, lo que causaba una primera consulta lenta. Ahora tiene suficiente para mantenerlos a todos en la memoria, de modo que el problema desaparezca. –

+0

Mi pregunta es, ¿es posible hacer la primera consulta más rápido? ¿O es lo que es, y subir el grupo de búferes es la forma correcta de hacerlo? –

3

¿Hay algo más ejecutándose en su servidor mysql? Mi pensamiento es que tal vez después de la primera consulta, tu tabla todavía está almacenada en la memoria caché. Una vez que está inactivo, otro proceso está causando que se elimine de la memoria caché. Sólo una suposición sin embargo.

¿Cuánta memoria tiene qué más se está ejecutando?

+0

mysql es lo único que se ejecuta en el servidor. Tiene 16Gb de memoria. Estoy de acuerdo con que se elimine de la memoria caché, pero no puedo averiguar dónde está almacenando en caché para poder solucionar el problema. No estoy seguro de si se trata de un problema de configuración de mysql, problema de configuración de Linux, problema de sql, etc. Busqué en Google que otros tuvieran el mismo problema, pero no había una idea de cuál era el problema. –

+0

Basado en esto: http://dev.mysql.com/doc/refman/5.1/en/query-cache.html, quizás intente hacer que query_cache_size sea más grande. Sin embargo, es extraño, porque Linux debería guardar automáticamente estas cosas en caché, ya sea que MySQL se lo indique o no. También podría probar métodos de propósito general para agilizar sus consultas, como agregar un índice y no tener tablas enormes, pero no sé si esas serían útiles para usted. –

+0

query_cache_size se establece en cero, por lo que este no es el problema. Quiero saber qué está almacenando en caché. –

0

Trate y compare la salida de "vmstat 1" en la línea de comandos de Linux cuando ejecuta la consulta después de un período de tiempo, frente a cuando la vuelve a ejecutar y obtiene resultados rápidamente. Específicamente, verifique la columna "bi" (esa es la lectura de kb del disco por segundo).

Puede encontrar que el sistema operativo está almacenando en caché los bloques de disco en la carcasa rápida (y por lo tanto una baja cifra "bi"), pero no en la carcasa lenta (y por lo tanto una gran figura "bi").

También puede encontrar que vmstat muestra un uso alto/bajo de la CPU en cualquier caso. Si es bajo cuando es rápido, y el rendimiento del disco también es bajo, entonces su sistema aún puede estar devolviendo una consulta en caché, aunque haya indicado que el valor de configuración relevante está establecido en cero. Tal vez consulte la salida de show engine innodb status y SHOW VARIABLES y confirme.

innodb_buffer_pool_size también puede establecerse en un valor alto (debería ser ...), lo que almacenaría en caché los bloques incluso antes de que el SO pueda devolverlos.

También puede encontrar que "key_buffer" tiene un valor alto: esto almacenaría en caché las claves de los índices, lo que podría hacer que su selección sea deslumbrantemente rápida.

Pruebe el sitio mysql performance blog para obtener mucha información útil.

+0

Esto es lo que está pasando. El servidor está leyendo la tabla innodb del disco en la primera consulta y luego usa la memoria caché cuando ejecuta consultas similares. Ahora tengo que descubrir cómo reducir el tamaño de ibdata1. Teniendo en cuenta mudarse a innodb_file_per_table –

1

Tenía un paquete de SSIS que estaba agotando el tiempo. La consulta era muy simple, a partir de una sola tabla MySQL, pero a veces devolvía muchos registros y algunas veces tardaba unos minutos en ejecutarse inicialmente, y luego solo unos pocos milisegundos después si quería consultarlo nuevamente. Estábamos atrapados con la conexión ADO, lo que significaba que se agotaría el tiempo de espera después de 30 segundos, por lo que la mitad de las bases de datos que estábamos tratando de cargar fallaron.

Después de golpear mi cabeza contra la pared intenté realizar primero una consulta inicial; muy simple y solo devuelve unas pocas filas. Como era tan simple, se ejecutó rápidamente y estableció la tabla en el caché para consultas más rápidas. En el siguiente paso del paquete haría la consulta más compleja que devolvió el gran conjunto de datos que mantuvo el tiempo de espera. Problema solucionado: todas las tablas cargadas. Puedo comenzar a hacer esto regularmente, las consultas complejas se ejecutan mucho más rápido haciendo primero una consulta simple.

+0

¿Quiere decir que puede ejecutar una pequeña consulta más su gran consulta original en menos tiempo que solo la consulta grande? Uno pensaría que MySQL resolvería esto y movería lo que necesita a la memoria incluso antes de intentar la gran consulta. – mpen

0

Tuve un problema cuando MySQL 5.6 era lento en la primera consulta después del período de inactividad. Este fue un problema de conexión, no un problema de instancia de MySQL, p. si ejecuta MYSQL Query Browser ejecute "select * from some_queue", déjelo solo durante un par de horas, luego ejecute cualquier consulta, se ejecuta lentamente, mientras que al mismo tiempo los procesos en el servidor o la nueva instancia del navegador seleccionarán de las mismas tablas instantáneamente.

Añadiendo skip-host-cache, skip-name-resolve a mi archivo .ini resolvió este problema.

No sé por qué es eso. Por qué intenté esto: MySQL 5.1 sin esas opciones poco a poco estaba estableciendo conexiones desde otras redes (por ejemplo, el servidor es 192.168.1.100, 192.168.1.101 conecta rápido, 192.168.2.100 conecta lento), MySQL 5.6 no tuvo ese problema para empezar, entonces no agregamos estos a my.ini inicialmente.

UPD: Solucionado la mitad de los casos, en realidad. Al establecer wait_timeout en el entero máximo, se corrigió la otra mitad. Tal vez incluso ahora puedo eliminar skip-host-cache, skip-name-resolve y no se ralentizará en el 100% de los casos

Cuestiones relacionadas