将MySQL表加载到Python中比R要慢得多

9

我有一张相当大的MySQL表,大约有3000万行,6列,加载到内存中后大约为2GB。

我同时使用Python和R。在R中,我可以将表加载到内存中,需要大约90秒的时间。但是在Python中,需要40分钟的时间。

我已经尝试过使用sqlalchemy和普通的pymysql进行操作。代码很简单,例如,在sqlalchemy中:

db_engine = sqlalchemy.create_engine("mysql+pymysql://user:pass@host/database")
cnx = db_engine.connect()
table = pd.read_sql('select * from my_table',cnx)
cnx.close()

没有使用SQLAlchemy:

cnx = mysql.connector.connect(**db_details)
cursor = cnx.cursor()
cursor.execute('select * from my_table')
table = pd.DataFrame(data=list(cursor),columns = cursor.column_names)
cnx.close()

无论如何,它比R慢得多,这对我来说没有多大意义。为什么会这样,有没有任何方法可以加速?即使是hack也可以。
另外,pandas与其花费的时间无关。在第二个代码片段中,如果我只返回list(cursor)而不是将其放入pandas DataFrame中,它需要(基本上)同样长的时间。
编辑: 数据库正在与R / Python相同的机器上运行,因此吞吐量方面应该是相同的。
在R中,我使用DBI,我使用的R代码(基本上)是这样的:
require(DBI)
cnx <- dbConnect(dbDriver("MySQL"),dbname="database",username="user",password="pass",host="host")
table <- dbGetQuery(cnx,"select * from my_table")

******** 已解决(大部分)********

感谢有用的评论,特别是@roganjosh的评论,问题似乎是默认的mysql连接器是用python编写的,而不是C语言,这使得它非常慢。解决方法是使用本地C连接器MySQLdb

在我的特定设置中,使用anaconda运行python 3是不可能的,因为MySQLdb仅支持python 2。然而,在名称为mysqlclient的python 3下有一个实现MySQLdb

使用这个实现,读取整个表格的时间现在缩短到了约5分钟,虽然不如R快,但比以前的40多倍要快得多。


我会将转换独立成为一个 pandas 数据帧,但这确实很有趣。 - Ma0
1
我猜你已经搜索过了吧?我对这个问题很感兴趣,实际上有很多人抱怨Python相比其他语言的性能。你看过这里接受的答案了吗(https://dev59.com/tYTca4cB1Zd3GeqPBfIK)?它有用吗? - roganjosh
1
我已经做了一些搜索,但没有找到答案。这似乎需要MySqlDb,我现在正在尝试安装,但在anaconda和python 3.5上没有成功。但如果连接器是用Python编写的,那么它运行缓慢是有道理的。 - mrip
1
哎呀,这可能是个问题。我用的是Windows,所以如果安装有困难,我总是去非官方二进制文件,所以如果你也在Windows上,我建议你这样做。但是我刚刚看到他只有2.7....而且我从来没有见过他的收藏过时。它可能不存在于Python 3中 :(. 如果是这种情况,您可以使用rpy运行查询,但这不是最理想的选择。 - roganjosh
1
我找到了一个叫做mysqlclient的东西,它声称是MySqlDb的实现,可以与Python 3一起使用。我们试试看。谢谢你的帮助。 - mrip
显示剩余9条评论
2个回答

4
感谢@roganjosh的有益评论,问题似乎是默认的mysql连接器是用Python而不是C编写的,这使得速度非常慢。解决方法是使用原生C连接器MySQLdb
在我的特定设置中,运行带有Anaconda的Python 3,这是不可能的,因为MySQLdb仅支持Python 2。但是,在名为mysqlclient下有Python 3的MySQLdb实现。
使用此实现,读取整个表的时间现在已经降至约5分钟,虽然不及R快,但比以前的40分钟要少得多。
我仍然希望听取能够加快速度的建议,但我猜这已经是最好的了。

0

还有一个纯C/C++ ultramysql MySQL驱动程序,可以与umysqldb适配器一起使用。这些项目已经不再活跃,但可能对某些一次性的事情有用 - 我不会在生产中使用它们。

由于pymysql是一个纯Python驱动程序,您也可以尝试在PyPy上运行它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接