NZa*_*Zal 35 python cursor mysql-python
两种方法都返回查询返回项的列表,我在这里错过了什么吗?
或者他们确实有相同的用法?
任何性能差异?
unu*_*tbu 71
如果您使用的是默认光标a MySQLdb.cursors.Cursor,则整个结果集将在完成时存储在客户端(即Python列表中)cursor.execute().
因此,即使你使用
for row in cursor:
Run Code Online (Sandbox Code Playgroud)
你不会减少内存占用.整个结果集已经存储在一个列表中(参见self._rowsMySQLdb/cursors.py).
但是,如果您使用SSCursor或SSDictCursor:
import MySQLdb
import MySQLdb.cursors as cursors
conn = MySQLdb.connect(..., cursorclass=cursors.SSCursor)
Run Code Online (Sandbox Code Playgroud)
然后结果集存储在服务器 mysqld中.现在你可以写了
cursor = conn.cursor()
cursor.execute('SELECT * FROM HUGETABLE')
for row in cursor:
print(row)
Run Code Online (Sandbox Code Playgroud)
并且这些行将从服务器逐个获取,因此不需要Python首先构建庞大的元组列表,从而节省内存.
否则,正如其他人已经说过的那样,cursor.fetchall()并且list(cursor)基本上是相同的.
Amb*_*ber 11
cursor.fetchall()并且list(cursor)基本上是相同的.不同的选择是不检索列表,而只是循环遍历裸光标对象:
for result in cursor:
Run Code Online (Sandbox Code Playgroud)
如果结果集很大,这可能会更有效,因为它不必获取整个结果集并将其全部保存在内存中; 它可以逐步获得每个项目(或以较小的批次批量处理).
list(cursor)之所以有效,是因为游标是可迭代的;您也可以cursor在循环中使用:
for row in cursor:
# ...
Run Code Online (Sandbox Code Playgroud)
一个好的数据库适配器实现将从服务器批量获取行,节省所需的内存占用,因为它不需要将完整的结果集保存在内存中。cursor.fetchall() 必须返回完整列表。
使用list(cursor)over没有什么意义cursor.fetchall();最终效果确实是一样的,但你浪费了一个机会来传输结果。
使用 a 时值得注意的一个(MySQLdb/PyMySQL 特定)差异DictCursor是,它list(cursor)总是为您提供一个列表,而 while 则为cursor.fetchall()您提供一个列表,除非结果集为空,在这种情况下,它会为您提供一个空元组。MySQLdb 中就是这种情况,并且在较新的PyMySQL中仍然是这种情况,由于向后兼容性原因,它不会被修复。虽然这并不违反 Python 数据库 API 规范,但它仍然令人惊讶,并且很容易因错误地假设结果是列表而不仅仅是序列而导致类型错误。
鉴于上述情况,我建议始终偏爱list(cursor),cursor.fetchall()以避免在结果集为空的边缘情况下陷入神秘的类型错误。