MySQLdb在处理大结果集时非常慢
我在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一样的限制,这样就可以比较一下处理时间。