2011-05-13 26 views
7

Ejecuté la siguiente consulta en phpMyAdmin & MySQLdb (python).MySQLdb es extremadamente lento con grandes conjuntos de resultados

SELECT *, (SELECT CONCAT(`id`, '|', `name`, '|', `image_code`) 
FROM `model_artist` WHERE `id` = `artist_id`) as artist_data, 
FIND_IN_SET("metallica", `searchable_words`) as find_0 
FROM `model_song` HAVING find_0 

phpMyAdmin dijo que la consulta tardó 2ms. Mi código python decía que usando MySQLdb la consulta tomó 848ms (sin siquiera obtener los resultados).

El código Python:

self.db = MySQLdb.connect(host="localhost", user="root", passwd="", db="ibeat") 
self.cur = self.db.cursor() 

millis = lambda: time.time() * 1000 

start_time = millis() 
self.cur.execute_cmd("""SELECT *, (SELECT CONCAT(`id`, '|', `name`, '|', `image_code`) 
FROM `model_artist` WHERE `id` = `artist_id`) as artist_data, 
FIND_IN_SET("metallica", `searchable_words`) as find_0 
FROM `model_song` HAVING find_0""") 
print millis() - start_time 
+0

Si ejecuta la consulta en línea de comandos de MySQL, ¿a qué hora se obtiene? – dusan

+0

¿Cuántos registros se devuelven? ¿Está seguro? PhpMyAdmin realizó la consulta? –

Respuesta

4

phpMyAdmin pone un límite a todas las consultas para que no regrese grandes conjuntos de resultados en la interfaz. Por lo tanto, si su consulta normalmente devuelve 1,000,000 de filas, y PHPMyAdmin reduce eso a 1,000 (o lo que sea el valor predeterminado), entonces tendría que esperar mucho más tiempo de procesamiento cuando Python tome o incluso consulte el conjunto de resultados completo.

Intenta poner un límite en Python que coincida con el límite en PHPMyAdmin para comparar tiempos.

+0

Lo descubrí pero no vi su respuesta ... Sin embargo, aceptaré la suya: P –

13

Si espera que una consulta SQL tenga un gran conjunto de resultados que luego planea iterar registro por registro, entonces puede considerar usar el MySQLdb SSCursor en lugar del cursor predeterminado. El cursor predeterminado almacena el conjunto de resultados en el cliente, mientras que el SSCursor almacena el conjunto de resultados en el servidor. A diferencia del cursor predeterminado, el SSCursor no incurrirá en un gran retraso inicial si todo lo que necesita hacer es iterar sobre los registros uno a uno.

Puede encontrar un poco de código de ejemplo en how to use the SSCursor here.

Por ejemplo, pruebe:

import MySQLdb.cursors 

self.db = MySQLdb.connect(host="localhost", user="root", passwd="", db="ibeat", 
          cursorclass = MySQLdb.cursors.SSCursor) 

(. El resto del código puede seguir siendo el mismo)

+0

Gracias por la información :) –

+3

O si usa DictCursor, reemplácela por SSDictCursor para que los resultados se devuelvan como una lista de diccionarios. –

Cuestiones relacionadas