MySQL ResultSets по умолчанию полностью извлекается с сервера, прежде чем можно будет выполнить какую-либо работу. В случае огромных наборов результатов это становится непригодным для использования. Вместо этого я бы хотел получить строки по очереди с сервера.
В Java, следуя инструкциям здесь (в разделе "ResultSet"), я создаю следующее утверждение:
stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
Это хорошо работает в Java. Мой вопрос: есть ли способ сделать то же самое в Python?
Я пытался ограничить запрос до 1000 строк за раз, например:
start_row = 0
while True:
cursor = conn.cursor()
cursor.execute("SELECT item FROM items LIMIT %d,1000" % start_row)
rows = cursor.fetchall()
if not rows:
break
start_row += 1000
# Do something with rows...
Тем не менее, это выглядит медленнее, чем выше start_row.
И нет, использование fetchone()
вместо fetchall()
ничего не меняет.
Пояснение:
Наивный код, который я использую для воспроизведения этой проблемы, выглядит следующим образом:
import MySQLdb
conn = MySQLdb.connect(user="user", passwd="password", db="mydb")
cur = conn.cursor()
print "Executing query"
cur.execute("SELECT * FROM bigtable");
print "Starting loop"
row = cur.fetchone()
while row is not None:
print ", ".join([str(c) for c in row])
row = cur.fetchone()
cur.close()
conn.close()
В таблице ~ 700 000 строк этот код выполняется быстро. Но в таблице ~ 9 000 000 строк она печатает «Выполнение запроса», а затем зависает надолго. Вот почему не имеет значения, если я использую fetchone()
или fetchall()
.