MySQLdb 对于大型结果集非常慢
我在 phpMyAdmin 和 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 表示查询花费了2ms。 我的Python代码说使用MySQLdb查询花费了848ms(甚至没有获取结果)。
蟒蛇代码:
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
I executed the following query both in 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 said the query took 2ms.
My python code said that using MySQLdb the query took 848ms (without even fetching the results).
The python code:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您希望 SQL 查询有一个大型结果集,然后计划逐条记录地迭代该结果集,那么您可能需要考虑使用 MySQLdb SSCursor 而不是默认游标。默认游标将结果集存储在客户端,而 SSCursor 将结果集存储在服务器中。与默认游标不同,如果您需要做的只是逐一迭代记录,SSCursor 不会产生较大的初始延迟。
您可以在此处找到一些有关如何使用 SSCursor 的示例代码。
例如,尝试:(
其余代码可以保持不变。)
If you expect an SQL query to have a large result set which you then plan to iterate over record-by-record, then you may want to consider using the MySQLdb SSCursor instead of the default cursor. The default cursor stores the result set in the client, whereas the SSCursor stores the result set in the server. Unlike the default cursor, the SSCursor will not incur a large initial delay if all you need to do is iterate over the records one-by-one.
You can find a bit of example code on how to use the SSCursor here.
For example, try:
(The rest of the code can remain the same.)
PHPMyAdmin 对所有查询设置了限制,因此您不会在界面中返回大型结果集。因此,如果您的查询通常返回 1,000,000 行,而 PHPMyAdmin 将其减少到 1,000(或任何默认值),那么当 Python 获取甚至查询整个结果集时,您将不得不预期更长的处理时间。
尝试在 Python 中设置与 PHPMyAdmin 上的限制相匹配的限制来比较时间。
PHPMyAdmin places a limit on all queries so you don't return large result sets in the interface. So if your query normally returns 1,000,000 rows, and PHPMyAdmin reduces that to 1,000 (or whatever the default is), then you would have to expect a lot longer processing time when Python grabs or even queries the entire result set.
Try placing a limit in Python that matches the limit on PHPMyAdmin to compare times.