どちらのメソッドも返されたクエリの項目のリストを返します。彼らはまったく同じ用途を持っていますか?どのような違いパフォーマンス賢明?cursor.fetchall()対Pythonのリスト(カーソル)
答えて
デフォルトのカーソル、MySQLdb.cursors.Cursor
、を使用している場合、結果セット全体がcursor.execute()
が完了した時点で(すなわち、Pythonのリストに)クライアント側に保存されます。
したがって、あなたは
for row in cursor:
を使用している場合でも、あなたは、メモリフットプリントの減少を得ることはありません。結果セット全体はすでにリストに格納されています(MySQLdb/cursors.pyのself._rows
を参照)。あなたが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)
を書くことができますし、行はこのように最初のタプルの膨大なリストを構築するためにはPythonを必要としないため、メモリの節約、サーバから1つずつフェッチされます。
他にも既に述べたように、cursor.fetchall()
とlist(cursor)
は本質的に同じです。
list(cursor)
カーソルが反復可能であるために機能します。あなたはまた、ループ内でcursor
を使用することができます。
for row in cursor:
# ...
良いデータベースアダプタ実装は、それがに設定されフル結果を保持する必要がないので、必要なメモリフットプリントを節約、サーバーからのバッチで行をフェッチしますメモリ。 cursor.fetchall()
にはがあり、代わりに完全なリストを返します。
list(cursor)
を使用している点は、cursor.fetchall()
以上です。エンドエフェクトはまったく同じですが、代わりに結果をストリーミングする機会が無駄になりました。
cursor.fetchall()
およびlist(cursor)
は本質的に同じである。別のオプションは、リストを取得し、代わりに裸のカーソルオブジェクトの上だけでループしないことです。
for result in cursor:
それが全体の結果をフェッチする必要がないように、結果セットが大きい場合、これは、より効率的にすることができそれをすべてメモリに保存しておきます。それぞれのアイテムを段階的に取得することができます(またはバッチでバッチをバッチ処理することもできます)。
これは、ほとんどの[PEP 249](https://www.python.org/dev/peps/pep-0249)の実装には当てはまりますが、MySQLdbやPyMySQLではそうではありません。 'list(cursor) cursor.fetchall() '(後者はリストまたはタプルのいずれかを一貫して返さないため、前者は常に一貫してリストを返すので)、ほとんどのカーソル実装は反復処理を開始するとすぐにメモリ全体に結果セットを取得します。 –
A(のMySQLdb/PyMySQL固有の)注目に値する違いDictCursor
を使用すると、結果セットが、それはあなたを与える場合には、空でない限りcursor.fetchall()
はあなたにリストを与えながらlist(cursor)
は常に、あなたのリストを与えるということです空のタプル。これはMySQLdbのケースであり、より新しいバージョンのケースに残っていますPyMySQL、後方互換性の理由からwill not be fixedです。これはisn't a violation of Python Database API Specificationですが、まだ驚くべきことですが、シーケンスではなく、リストと誤って誤ってタイプエラーが発生する可能性があります。
上記を踏まえて、結果セットが空の奇妙なタイプのエラーによってキャッチされることを避けるため、常にlist(cursor)
をcursor.fetchall()
よりも優先することをお勧めします。
- 1. Oracleカーソル対SQL Serverカーソル
- 2. Pythonでsqlite3のcursor.fetchall()からUを削除する方法
- 3. Python cursor.fetchall()は空のタプルを返します
- 4. Pythonウィジェット/カーソル検出?
- 5. リストのアレイベースの実装(カーソルの実装)
- 6. Python-Oracleカーソルを渡すパラメータ
- 7. Python MySQLカーソル - パーセントをエスケープ
- 8. Pythonのリストに対応するディクショナリキー値の繰り返し
- 9. Pythonの文字列対リストの奇妙な動作
- 10. リストするリストのPythonリスト
- 11. T-SQL早送りカーソル対foreach
- 12. Python:リストにリスト
- 13. Pythonでカスタムオブジェクトのリストのリスト
- 14. Pythonの追加は、リスト+リスト
- 15. Python:リストのリストをソート
- 16. リスト形式のPythonリスト
- 17. はPythonのリスト
- 18. Pythonの:リスト
- 19. Pythonのitertools:リスト
- 20. Pythonのリスト/インデックスクエリ
- 21. コピーPythonのリスト
- 22. リストのPython json
- 23. Pythonのリスト
- 24. リストのPython値
- 25. Pythonのリストは、
- 26. pythonのweakrefリスト
- 27. Pythonのリストは
- 28. Pythonでカーソルを操作する
- 29. wget対Pythonのurlretrieve
- 30. Pythonのリストのスライス
* "cursor.fetchall()に比べてリスト(カーソル)を使用することはほとんどありませんが、最終的には同じ結果になりますが、代わりに結果をストリーミングする機会が無駄になります。 PythonデータベースAPI。 'cursor.fetchall()'が一貫性のない戻り値の型を持つMySQLdbやその後継者PyMySQLの特定のケースではあまり真実ではありません(常に 'list(cursor)'を使用すると、ほとんどのカーソル・サブクラスはループしてもストリーミングを行わず、代わりにすべての結果をメモリーに読み込んでから最初の結果を生成します。 –
@ MarkAmery:私は「良いデータベースアダプタの実装」という言葉を慎重に使用しています。私は、既存のMySQLの実装は、私が投稿を書いたときにすべての結果をプリフェッチしていると思っていました。 –