为什么Python中的线程MySQLdb查询比相同的非线程查询慢?

mud*_*dda 6 python mysql multithreading

我正在构建一个使用Python和MySQLdb运行MySQL查询的线程类.我不明白为什么运行这些查询线程比运行非线程更慢.这是我的代码,以显示我正在做什么.

首先,这是非线程函数.

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()
Run Code Online (Sandbox Code Playgroud)

这是我的线程类:

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()
Run Code Online (Sandbox Code Playgroud)

这是处理程序:

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()
Run Code Online (Sandbox Code Playgroud)

我不确定为什么这个线程代码运行得更慢.有趣的是,如果我使用相同的代码,只能做一些简单的像另外的数字,螺纹代码显著更快.

我明白我必须遗漏一些完全明显的东西,但是我们非常感谢任何支持!

sam*_*ias 0

您正在启动 N 个线程,每个线程都创建自己的 MySQL 连接,并且您正在使用同步队列将查询传递给线程。每个线程都阻塞queue.get()(获取独占锁)以获取查询,然后创建到数据库的连接,然后调用task_done()它让下一个线程继续。因此,当线程 1 工作时,N-1 个线程什么也不做。锁获取/释放的开销,加上连续创建和关闭多个数据库连接的额外开销加起来。

  • @mudda 这个答案是错误的。在调用“task_done”之前,Queue.get() 不会获取独占锁。那是胡说八道。当对同一个表进行多个查询时,MySQL 可能是您的瓶颈。虽然 MySQLdb 确实围绕某些操作释放了 GIL,但它在保留 GIL 的同时也做了重要的工作,导致了 GIL 争用,也可能解释了速度减慢的原因。 (5认同)