MySQLdb очень медленный с большими наборами результатов - PullRequest
7 голосов
/ 13 мая 2011

Я выполнил следующий запрос в 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

Ответы [ 2 ]

15 голосов
/ 13 мая 2011

Если вы ожидаете, что запрос SQL будет иметь большой набор результатов, который вы затем планируете выполнять итерацию по каждой записи, вы можете рассмотреть возможность использования MySQLdb SSCursor вместо курсора по умолчанию. Курсор по умолчанию сохраняет результирующий набор на клиенте, тогда как SSCursor сохраняет результирующий набор на сервере. В отличие от курсора по умолчанию, SSCursor не будет подвергаться большой начальной задержке, если все, что вам нужно сделать, это перебирать записи по одной.

Вы можете найти пример кода на , как использовать SSCursor здесь .

Например, попробуйте:

import MySQLdb.cursors

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

(остальная часть кода может остаться прежней.)

4 голосов
/ 13 мая 2011

PHPMyAdmin накладывает ограничение на все запросы, чтобы вы не возвращали большие наборы результатов в интерфейсе.Поэтому, если ваш запрос обычно возвращает 1 000 000 строк, а PHPMyAdmin уменьшает его до 1 000 (или любого другого значения по умолчанию), вам придется ожидать гораздо более длительного времени обработки, когда Python захватывает или даже запрашивает весь набор результатов.

Попробуйте установить ограничение в Python, соответствующее пределу PHPMyAdmin, чтобы сравнить время.

...