43

両方のメソッドは、クエリの返された項目のリストを返します。ここで何かを見逃していましたか、それとも同じ使用法を持っているのでしょうか?

性能的に違いはありますか?

4

5 に答える 5

77

デフォルトのカーソル a を使用している場合MySQLdb.cursors.Cursor、が完了するまでに、結果セット全体がクライアント側(つまり、Python リスト) に保存されますcursor.execute()

そのため、使用しても

for row in cursor:

メモリ フットプリントが減少することはありません。結果セット全体がすでにリストに格納されています ( self._rowsMySQLdb/cursors.py を参照)。

ただし、SSCursor または SSDictCursor を使用する場合:

import MySQLdb
import MySQLdb.cursors as cursors

conn = MySQLdb.connect(..., cursorclass=cursors.SSCursor)

次に、結果セットがサーバーmysqldに格納されます。今、あなたは書くことができます

cursor = conn.cursor()
cursor.execute('SELECT * FROM HUGETABLE')
for row in cursor:
    print(row)

行はサーバーから 1 つずつフェッチされるため、最初に Python で膨大な数のタプルのリストを作成する必要がなく、メモリを節約できます。

それ以外は、他の人がすでに述べているように、cursor.fetchall()本質list(cursor)的に同じです。

于 2013-07-25T15:08:48.003 に答える
14

cursor.fetchall()list(cursor)本質的に同じです。別のオプションは、リストを取得せず、代わりにそのままのカーソル オブジェクトをループすることです。

for result in cursor:

これは、結果セット全体を取得してすべてメモリに保持する必要がないため、結果セットが大きい場合により効率的です。各アイテムを段階的に取得できます(または、それらを小さなバッチでバッチ処理できます)。

于 2013-07-25T14:41:34.033 に答える
6

list(cursor)カーソルは反復可能であるため機能します。cursorループで使用することもできます:

for row in cursor:
    # ...

優れたデータベース アダプタの実装では、サーバーからバッチで行をフェッチし、完全な結果セットをメモリに保持する必要がないため、必要なメモリ フットプリントを節約します。代わりに完全なリストを返す必要がありますcursor.fetchall()

list(cursor)overを使用する意味はほとんどありませんcursor.fetchall()。最終的な結果は実際には同じですが、代わりに結果をストリーミングする機会を無駄にしました.

于 2013-07-25T14:41:26.503 に答える
5

(MySQLdb/PyMySQL 固有の) 違いDictCursorは、 a を使用するときlist(cursor)に常にリストをcursor.fetchall()提供する一方で、結果セットが空でない限りリストを提供し、その場合は空のタプルを提供します。これは MySQLdb の場合であり、後方互換性の理由から修正されない新しいPyMySQLの場合のままです。これは Python データベース API 仕様 の違反ではありませんが、それでも驚くべきことであり、結果が単なるシーケンスではなくリストであると誤って想定することにより、型エラーが発生しやすくなります。

上記を考慮して、結果セットが空のエッジケースで不思議な型エラーに巻き込まれないように、常に を優先list(cursor)することをお勧めします。cursor.fetchall()

于 2016-10-23T12:25:56.633 に答える