Estoy construyendo una clase de subprocesos para ejecutar consultas MySQL usando Python y MySQLdb. No entiendo por qué ejecutar estas consultas enhebradas es más lento que ejecutarlas sin subprocesos. Aquí está mi código para mostrar lo que estoy haciendo.¿Por qué las consultas MySQLdb enhebradas en Python son más lentas que las mismas consultas sin subprocesos?
Primero, aquí está la función no roscada.
def testQueryDo(query_list):
db = MySQLdb.connect('localhost', 'user', 'pass', 'db_name')
cursor = db.cursor()
q_list = query_list
for each in q_list:
cursor.execute(each)
results = cursor.fetchall()
db.close()
Aquí es mi clase de roscado:
class queryThread(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
self.db = MySQLdb.connect('localhost', 'user', 'pass', 'db_name')
self.cursor = self.db.cursor()
def run(self):
cur_query = self.queue.get()
self.cursor.execute(cur_query)
results = self.cursor.fetchall()
self.db.close()
self.queue.task_done()
Y es el manejador aquí:
def queryHandler(query_list):
queue = Queue.Queue()
for query in query_list:
queue.put(query)
total_queries = len(query_list)
for query in range(total_queries):
t = queryThread(queue)
t.setDaemon(True)
t.start()
queue.join()
No estoy seguro de por qué este código roscado va más lento. Lo que es interesante es que si uso el mismo código, solo hago algo simple como agregar números, el código enhebrado es significativamente más más rápido.
Entiendo que me debe estar perdiendo algo completamente obvio, sin embargo cualquier ayuda sería muy apreciada.
También CPython solo permite la ejecución de un hilo a la vez (debido a GIL) incluso si ... –
¡Ah, tenía la impresión de que se estaban ejecutando simultáneamente! Gracias samplebias! ¿Sería más eficiente si utilizo múltiples procesos para bifurcar cada consulta, o hay una forma mejor/más eficiente de hacerlo con el hilo que me falta? – mudda
Realmente depende de su aplicación, pero algunas cosas mejorarán el rendimiento de su ejemplo anterior: use un threadpool más pequeño y envíe varias consultas a cada thread en lugar de uno, haga que cada thread reutilice su conexión a la base de datos para múltiples consultas. Si decide usar 'fork', puede probar el módulo [multiprocesamiento] (http://docs.python.org/library/multiprocessing.html) para facilitar la comunicación con sus subprocesos. – samplebias