MySQLdb在处理大结果集时非常慢

7 投票
2 回答
5968 浏览
提问于 2025-04-16 17:35

我在phpMyAdmin和MySQLdb(用python)中执行了以下查询。

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显示这个查询花了2毫秒。而我的python代码显示,使用MySQLdb这个查询花了848毫秒(甚至还没有获取结果)。

这是我的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

2 个回答

15

如果你预计一个SQL查询会返回很多结果,而你又打算逐条记录地处理这些结果,那么你可以考虑使用MySQLdb的SSCursor,而不是默认的游标。默认的游标会把结果存储在客户端,而SSCursor则把结果存储在服务器上。与默认游标不同,SSCursor在你只需要逐条处理记录时,不会造成很大的初始延迟。

你可以在这里找到一些关于如何使用SSCursor的示例代码

例如,可以尝试:

import MySQLdb.cursors

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

(其余的代码可以保持不变。)

5

PHPMyAdmin对所有查询设置了一个限制,这样你在界面上就不会看到太大的结果集。比如说,如果你的查询通常会返回1,000,000行数据,但PHPMyAdmin把这个结果限制到1,000行(或者其他默认值),那么当你用Python获取或者查询整个结果集时,处理时间就会变得非常长。

你可以尝试在Python中设置一个和PHPMyAdmin一样的限制,这样就可以比较一下处理时间。

撰写回答