我在(本地)网络上的MySQL数据库中有500万行(所以快速连接,而不是在互联网上)。
与数据库的连接工作正常,但如果我尝试
f = pd.read_sql_query('SELECT * FROM mytable', engine, index_col = 'ID')
这需要真的很长时间。即使使用chunksize
进行分块也会很慢。此外,我真的不知道它是挂在那里还是确实在检索信息。
我想问一下,对于那些在数据库上处理大数据的人来说,他们如何为Pandas会话检索他们的数据?
例如,运行查询,返回带有结果的csv文件并将那个加载到Pandas中会更聪明吗?听起来比它需要的更多。
答案 0 :(得分:3)
将表中的所有数据从-any-SQL数据库中加载到pandas中的最佳方法是:
pandas.read_csv
function 仅将连接器用于读取几行。 SQL数据库的强大之处在于它能够根据索引提供小块数据。
使用转储执行整个表的传递。
答案 1 :(得分:2)
我在处理Oracle数据库时遇到了类似的问题(对我来说,事实证明它需要很长时间来检索所有数据,在此期间我不知道它有多远,或者是否有任何问题on) - 我的解决方案是将查询结果流式传输到一组csv文件中,然后将它们上传到Pandas中。
我确信有更快的方法可以做到这一点,但这对于大约800万行的数据集来说效果非常好。
你可以在我的Github页面上看到easy_query.py使用的代码,但我使用的核心功能如下:
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_csv和pandas.concat语句将它们加载到单个Pandas数据框中。
答案 2 :(得分:0)
query
:编写查询。
conn
:连接到数据库
chunksize
:分批提取数据。返回一个生成器。
请尝试以下代码以大块形式提取数据。然后使用该函数将生成器对象转换为数据框。
df_chunks = pd.read_sql_query(query, conn, chunksize=50000)
def chunks_to_df(gen):
chunks = []
for df in gen:
chunks.append(df)
return pd.concat(chunks).reset_index().drop('index', axis=1)
df = chunks_to_df(df_chunks)
这将帮助您减少数据库服务器上的负载,并批量获取所有数据并将其用于进一步分析。