Отключение кешированных результатов в mysql (с использованием python)

Я использую python 2.7, pyodbc и mysql 5.5. я на окнах

У меня есть запрос, который возвращает миллионы строк, и я хотел бы обрабатывать его по частям. с помощью функции fetchmany.

Он часть кода

import pyodbc
connection = pyodbc.connect('Driver={MySQL ODBC 5.1 Driver};Server=127.0.0.1;Port=3306;Database=XXXX;User=root; Password='';Option=3;')

cursor_1 = connection.cursor()
strSQLStatement = 'SELECT x1, x2 from X'

cursor_1.execute(strSQLStatement)
# the error occurs here  

x1 = cursor_1.fetchmany(10)
print x1
connection.close()

Моя проблема:

  1. Я получаю сообщение об ошибке У клиента MySQL недостаточно памяти

  2. Я предполагаю, что это потому, что cursor_1.execute пытается прочитать все в память и пробовал следующее (по одному), но безрезультатно

    1. In user interface (ODBC – admin tools) I ticked the “Don't cache results of forwarding-only cursors”
    2. connection.query("SET GLOBAL query_cache_size = 40000")

Мой вопрос:

  1. Есть ли у pyodbc возможность запускать запрос и предоставлять результаты только по запросу?

  2. В руководстве по MySQL предлагается вызывать mysql с параметром - -быстрый вариант. Можно ли это сделать также, когда не используется командная строка?

Спасибо за вашу помощь.

P.S: предложения по альтернативному модулю MySQL также приветствуются, но я использую портативный Python, поэтому мой выбор ограничен.


person user1043144    schedule 23.08.2012    source источник
comment
почему бы вам просто не использовать LIMIT 10 в самом запросе?   -  person Burhan Khalid    schedule 23.08.2012


Ответы (2)


Использование MySQLdb с SSCursor решит ваши вопросы.

К сожалению, документация невелика, но она упоминается в руководстве пользователя и вы можете найти пример в этом вопросе о стеке по потоку.

person Mihai Stan    schedule 23.08.2012
comment
Спасибо, Михай. Я бы очень хотел сделать это с помощью pyodbc или другого API БД, который без проблем работает в Windows (в переносной версии, которую я использую). Это не относится к окнам MySQLdb. Но все равно спасибо. - person user1043144; 23.08.2012
comment
Вы пробовали PyMySQL (чистый клиент Python)? он также поддерживает SSCursors, но у меня нет личного опыта с ним - person Mihai Stan; 23.08.2012
comment
Наконец-то я установил ActivePython и MySQLdb, но это не решает проблему. Есть еще проблема с памятью. На самом деле документация ‹mysql-python.sourceforge .net/MySQLdb-1.2.2/public/› говорит, что SSCursor сохраняет результаты на сервере (думаю, он все извлекает). Я также пытался установить размер массива cursor_1.arraysize= 2, но это не помогает. P.S: Не знал, что ActivePython на самом деле портабельный (есть zip-версия без установщика). MySQLdb называется там MySQL-python. другой связанный вопрос 337479 я буду использовать sqlite - person user1043144; 23.08.2012

Используйте предложение LIMIT в строке запроса.

http://dev.mysql.com/doc/refman/5.5/en/select.html

Используя

SELECT x1, x2 from X LIMIT 0,1000 

Вы получите только 1-й 1k записей, а затем выполните:

SELECT x1, x2 from X LIMIT 1000,2000 

Вы получите следующие 1k записей.

Зациклите это соответствующим образом, чтобы получить все ваши записи. (Я не знаю Python, поэтому здесь не могу помочь :()

person FreudianSlip    schedule 23.08.2012
comment
Спасибо. Это был бы крайний вариант (так сказать, ядерный вариант). - person user1043144; 23.08.2012
comment
Только что пришел к этому комментарию и хотел бы расширить комментарий выше. Это действительно ядерный вариант, потому что вы не указываете mysql, каким образом их упорядочивать. Если что-то было вставлено между двумя запросами, вы получите недетерминированные результаты b/c того, как mysql возвращает строки без порядка. А порядок по лимиту очень неэффективен, если его не зафиксировать. лучше было бы BETWEEN N AND M и следить за N и M самостоятельно. - person ekydfejj; 10.01.2019