Python 大熊猫SQL块大小
这与其说是编程问题,不如说是理解问题。 我对熊猫和SQL很陌生。我使用pandas从SQL中读取具有特定块大小的数据。 当我运行sql查询时,例如。 作为pd进口熊猫Python 大熊猫SQL块大小,python,sql-server,pandas,chunks,Python,Sql Server,Pandas,Chunks,这与其说是编程问题,不如说是理解问题。 我对熊猫和SQL很陌生。我使用pandas从SQL中读取具有特定块大小的数据。 当我运行sql查询时,例如。 作为pd进口熊猫 df = pd.read_sql_query('select name, birthdate from table1', chunksize = 1000) 我不明白的是,当我没有给出chunksize时,数据存储在内存中,我可以看到内存在增长。然而,当我给出chunksize时,内存使用率并没有那么高 我得到的是,这个df现在
df = pd.read_sql_query('select name, birthdate from table1', chunksize = 1000)
我不明白的是,当我没有给出chunksize时,数据存储在内存中,我可以看到内存在增长。然而,当我给出chunksize时,内存使用率并没有那么高
我得到的是,这个df现在包含了一些数组,我可以作为
for df_array in df:
print df.head(5)
这里我不理解的是,SQL语句的整个结果是否保存在内存中,即df是一个携带多个数组的对象,或者这些数组是否类似于指向SQL查询创建的临时表的指针
我很高兴能对这一过程的实际情况有所了解。
让我们考虑两种选择,两种情况都会发生什么:
- 将查询传递到数据库
- 数据库执行查询
- pandas检查并发现chunksize为None
- pandas告诉数据库它希望一次接收结果表的所有行
- 数据库返回结果表的所有行
- pandas将结果表存储在内存中,并将其包装到数据帧中
- 现在您可以使用数据帧了
- 将查询传递到数据库
- 数据库执行查询
- pandas检查并发现chunksize有一些值
- pandas创建一个查询迭代器(通常是“while True”循环,当数据库说没有更多的数据留下时循环中断),并在每次需要结果表的下一个块时对其进行迭代
- pandas告诉数据库它希望接收chunksize行
- 数据库从结果表返回下一个chunksize行
- pandas将下一个chunksize行存储在内存中,并将其包装到数据帧中
- 现在您可以使用数据帧了
要了解更多详细信息,您可以查看模块,它有很好的文档记录当您不提供
chunksize
时,查询的完整结果会立即放入数据帧中
当您提供chunksize
时,read\u sql\u query
的返回值是多个数据帧的迭代器。这意味着您可以像这样迭代:
for df in result:
print df
在每个步骤中,df
是一个数据帧(不是数组!),它保存查询的一部分数据。请参阅本页上的文档:
要回答有关内存的问题,您必须知道从数据库检索数据有两个步骤:execute
和fetch
首先执行查询(
result=con.execute()
),然后将数据作为元组列表从该结果集中提取(data=result.fetch()
)。提取时,可以指定要一次提取多少行。当您提供chunksize
但是,许多数据库驱动程序已经在执行步骤中将所有数据放入内存,而不仅仅是在获取数据时。因此,在这方面,这对记忆应该没有多大影响。除了使用
chunksize
进行迭代时,将数据复制到数据帧中只需不同的步骤,这基本上是为了防止服务器在进行大规模查询时内存不足
输出到CSV
for chunk in pd.read_sql_query(sql , con, chunksize=10000):
chunk.to_csv(os.path.join(tablename + ".csv"), mode='a',sep=',',encoding='utf-8')
还是去拼花地板
count = 0
folder_path = 'path/to/output'
for chunk in pd.read_sql_query(sql , con, chunksize=10000):
file_path = folder_path + '/part.%s.parquet' % (count)
chunk.to_parquet(file_path, engine='pyarrow')
count += 1
请注意,@joris的回答中提到,
许多数据库驱动程序已经在执行步骤中将所有数据放入内存中
。所以chunksize在很多情况下对内存使用没有多大帮助。