2011-05-13 28 views
7

我在phpMyAdmin & MySQLdb(python)中執行了以下查詢。MySQLdb對於大型結果集極其緩慢

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(甚至沒有提取結果)。

的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 
+0

,你得到了什麼時間? – dusan 2011-05-13 15:51:01

+0

正在返回多少條記錄?你是否_sure_ phpMyAdmin執行查詢? – 2011-05-13 15:51:04

回答

4

的phpMyAdmin放在所有查詢的限制,所以你不會在界面返回大結果集。因此,如果您的查詢通常返回1,000,000行,並且PHPMyAdmin將其減少到1,000(或任何默認值),那麼當Python抓取甚至查詢整個結果集時,您將需要更長的處理時間。

嘗試在Python中添加一個與PHPMyAdmin上的限制相匹配的限制來比較時間。

+0

我想通了,但沒有看到你的答案......但我會接受你的答案:P – 2011-05-13 15:53:06

13

如果您希望SQL查詢具有較大的結果集,然後您計劃逐個記錄地迭代,那麼您可能需要考慮使用MySQLdb SSCursor而不是缺省遊標。默認遊標將結果集存儲在客戶端中,而SSCursor將結果集存儲在服務器中。與默認遊標不同,如果您只需逐個遍歷記錄,則SSCursor不會產生較大的初始延遲。

你可以在how to use the SSCursor here上找到一些示例代碼。

例如,嘗試:如果您運行MySQL命令行查詢

import MySQLdb.cursors 

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

(該代碼的其餘部分可以保持不變)

+0

感謝您的信息:) – 2011-05-13 16:04:04

+3

或者如果您使用DictCursor,請用SSDictCursor替換它,以便返回結果作爲字典列表。 – 2012-11-07 21:57:18