从MySQL向Pandas加载500万行
我在一个MySQL数据库中有500万行位于(本地)网络上(如此快速的连接,而不是在互联网上) 与数据库的连接工作正常,但如果我尝试从MySQL向Pandas加载500万行,mysql,pandas,Mysql,Pandas,我在一个MySQL数据库中有500万行位于(本地)网络上(如此快速的连接,而不是在互联网上) 与数据库的连接工作正常,但如果我尝试 f = pd.read_sql_query('SELECT * FROM mytable', engine, index_col = 'ID') 这需要很长时间。即使使用chunksize进行分块也会很慢。此外,我真的不知道它是挂在那里还是真的在检索信息 我想问一下,对于那些在数据库上处理大数据的人,他们如何为他们的会话检索数据 例如,运行查询、返回一个包含结果的
f = pd.read_sql_query('SELECT * FROM mytable', engine, index_col = 'ID')
这需要很长时间。即使使用chunksize
进行分块也会很慢。此外,我真的不知道它是挂在那里还是真的在检索信息
我想问一下,对于那些在数据库上处理大数据的人,他们如何为他们的会话检索数据
例如,运行查询、返回一个包含结果的csv文件并将其加载到Pandas中是否更“智能”?听起来比它需要的要复杂得多。将表中的所有数据从任何SQL数据库加载到pandas中的最佳方法是:
交付整个表是处理转储的工作。在使用Oracle db时,我遇到了类似的问题(对我来说,检索所有数据花费了很长时间,在这段时间内,我不知道它有多远,也不知道是否存在任何问题)-我的解决方案是将查询结果流式传输到一组csv文件中,然后将其上载到Pandas中 我确信有更快的方法可以做到这一点,但对于大约800万行的数据集来说,这种方法出人意料地有效 您可以在我的Github页面上看到我用于的代码,但我使用的核心函数如下所示:
def SQLCurtoCSV (sqlstring, connstring, filename, chunksize):
connection = ora.connect(connstring)
cursor = connection.cursor()
params = []
cursor.execute(sqlstring, params)
cursor.arraysize = 256
r=[]
c=0
i=0
for row in cursor:
c=c+1
r.append(row)
if c >= chunksize:
c = 0
i=i+1
df = pd.DataFrame.from_records(r)
df.columns = [rec[0] for rec in cursor.description]
df.to_csv(filename.replace('%%',str(i)), sep='|')
df = None
r = []
if i==0:
df = pd.DataFrame.from_records(r)
df.columns = [rec[0] for rec in cursor.description]
df.to_csv(filename.replace('%%',str(i)), sep='|')
df = None
r = []
周围的模块导入cx_Oracle,以提供各种数据库钩子/api调用,但我希望使用一些类似提供的MySQL api可以提供类似的函数
很好的是,您可以看到文件在您选择的目录中堆积,因此您可以得到一些关于您的提取是否有效以及每秒/分钟/小时可以收到多少结果的反馈
这还意味着您可以在提取其余文件的同时处理初始文件
将所有数据保存到单个文件后,可以使用多个Pandas.read\u csv和Pandas.concat语句将它们加载到单个Pandas数据框中。
查询
:编写查询。conn
:连接到数据库chunksize
:分批提取数据。返回一个生成器
请尝试下面的代码以块的形式提取数据。然后使用函数将生成器对象转换为数据帧
df\u chunks=pd.read\u sql\u查询(查询,连接,chunksize=50000)
def块到df(gen):
块=[]
对于发电机中的df:
chunks.append(df)
返回pd.concat(chunks).reset_index().drop('index',axis=1)
df=块到块df(df\u块)
这将帮助您减少数据库服务器上的负载,分批获取所有数据并将其用于进一步分析。不要检索500万条记录,尤其是对于宽表,I/O将杀死您。@dbugger:是的,对不起,上面的查询只是一个示例,我不
从表中选择*
,但如果我,为相对较小的记录子集(>10%)创建迭代器永远不会结束。。。所以我认为我的工作流程有问题。谢谢。为了确保没有其他问题(除了大小),如果您在查询中添加限制100
(或更大),它将按预期工作?您是否将此与使用pd.read\u sql\u查询进行比较?由于此函数的作用基本相同(调用execute
,然后调用fetchmany
(如果使用chunksize)),因此我认为read\u sql\u query
更易于使用,甚至更快。我不得不说,我没有这样做,但取决于它如何管理chuncksize参数,这看起来可能是一个解决方案。问:它如何处理chunksize参数?e、 假设我的查询将返回500万行,chunksize为100000,结果会是什么?我从来没有真正理解过chunksize是如何工作的。[稍后编辑]刚刚发现了[this](),这表明有一种chunking对象允许在主数据集上进行分级查看-所以是的,可能就是这样。上面的完整代码大致类似于:for chunk in pd.read_sql_query(…chunksize=…):chunk.to_csv(…)
。但是问题是是否仍然需要将其分块写入csv。如果您不想手动执行此操作,请查看odo
:这不会改变服务器上的行为,除非您设置执行选项(stream\u results=True)
。看见