为什么Python中获取postgreSQL表的速度比R慢得多?
我必须对存储在PostgreSQL表中的数据进行一些统计处理。我一直在犹豫使用R和Python 对于R,我使用以下代码:为什么Python中获取postgreSQL表的速度比R慢得多?,python,r,postgresql,Python,R,Postgresql,我必须对存储在PostgreSQL表中的数据进行一些统计处理。我一直在犹豫使用R和Python 对于R,我使用以下代码: require("RPostgreSQL") (...) #connection to the database, etc my_table <- dbGetQuery(con, "SELECT * FROM some_table;") import psycopg2 conn = psycopg2.connect(conn_string) cursor = co
require("RPostgreSQL")
(...) #connection to the database, etc
my_table <- dbGetQuery(con, "SELECT * FROM some_table;")
import psycopg2
conn = psycopg2.connect(conn_string)
cursor = conn.cursor()
cursor.execute("SELECT * FROM some_table;")
my_table = cursor.fetchall()
令人惊讶的是,它导致我的Python会话冻结,我的计算机崩溃
当我使用这些库作为“黑匣子”时,我不明白为什么在R中如此快速的东西在Python中会如此缓慢(因此几乎不可能实际使用)
有人能解释一下性能上的差异吗?有人能告诉我是否存在一种更有效的方法来获取Python中的pgSQL表吗?我不是R方面的专家,但非常明显的是什么
dbGetQuery()
(实际上是什么dbFetch()
)returns是一个懒惰的对象,它不会将所有结果加载到内存中——否则它当然会花费很长时间,并吃掉所有的ram
wrt/Python/psycopg,您肯定不想fetchall()
一个巨大的数据集。这里的正确解决方案是对其进行搜索和迭代
编辑-回答评论中的问题:
因此,在执行fetchall()时,选项cursor\u factory=psycopg2.extras.DictCursor起作用,对吗
一点也不。正如我喜欢的示例中的所有字母所述,“技巧”是使用服务器端游标,这是通过命名游标(在psycopg中)来完成的:
下面是重要的部分,为光标指定名称
psycopg2创建一个服务器端游标,用于阻止所有
从服务器上一次下载的记录
DictCursor的内容实际上是不相关的(在本例中不应提及,因为它显然会让新手感到困惑)
关于lazy对象(在R中返回的对象)的概念,我有一个附带问题。如何能够将对象作为数据帧返回,而不将其存储在RAM中?我觉得它有点神奇 正如我提到的,我对R及其实现没有太多了解——我从您描述的行为推断,
dbFetch
返回的任何东西都是一个懒惰的对象——但是拥有一个从外部源懒洋洋地获取值的对象并没有什么神奇之处。Python的文件
对象就是一个已知的示例:
with open("/some/huge/file.txt") as f:
for line in f:
print line
在上面的代码片段中,文件
对象f
仅在需要时从磁盘获取数据。需要存储的只是文件指针位置(以及从磁盘读取的最后N个字节的缓冲区,但这是一个实现细节)
如果您想了解更多信息,.与
dbGetQuery
是否类似于execute
,即执行该行时不会获取任何结果?这看起来像是一个非常简单的psycopg2示例,它做的事情应该没有问题。如果进行此查询会导致整个计算机停机,那么我会开始怀疑您的python或psycopg2模块安装是否以某种方式损坏?fetchone()
表现如何?@GuyBrush这种工作方式是通过使用dbSendQuery
和fetch
来完成的。@GuyBrush我真的不理解你的评论@匹配我再次尝试使用限制为20行的SQL查询。(这里是mySQL而不是postgreSQL,但我认为这并不重要)fetchall()
在20行的表格中工作起来就像一个符咒,但是fetchone()
返回以下错误:mysql.connector.errors.InternalError:Unread result found
所以在执行fetchall()
时选项cursor\u factory=psycopg2.extras.DictCursor
起作用,对吗?这很奇怪,因为我已经在VBA中做过类似的事情,并且我100%确定当时我使用的是客户端游标。我有一个关于惰性对象概念的附带问题(在R中返回的)。如何能够将对象作为数据帧返回,而不将其存储在RAM中?我觉得它有点神奇。
with open("/some/huge/file.txt") as f:
for line in f:
print line