Python 2.7 pyodbc 或 pymssql 与 R RODBC

Posted

技术标签:

【中文标题】Python 2.7 pyodbc 或 pymssql 与 R RODBC【英文标题】:Python 2.7 pyodbc or pymssql vs R RODBC 【发布时间】:2016-02-01 13:14:40 【问题描述】:

我正在尝试将 R 代码迁移到 Python 2.7 以比较两者。我遇到的第一个问题是当我尝试进行 odbc 连接时。 R 比 python 快得多,但由于我是 Python 新手,我不确定我是否使用了正确的包。

我在 R 中写道:

ptm <- proc.time()
require(RODBC)
dbXX <- odbcDriverConnect('driver=SQL Server;
    server=s001111;database=XX;trusted_connection=true')
rech<-sqlQuery(dbXX, "select top 10000* from XX.dbo.table ", as.is=T)
proc.time() - ptm

我得到:

> proc.time() - ptm
   user  system elapsed 
   2.47    0.11    2.87 

我已经为 python 2.7 windows 7 64 下载了 Anaconda。 所以我在 Spyder 中写道:

import pyodbc
import pandas
from pandas.io.sql import read_frame
sql = 'select top 10000 * from XX.dbo.table'
cnn = pyodbc.connect('DRIVER=SQL Server;SERVER=s001111;DATABASE=XX;Trusted_Connection=yes')

start = time.time()
data=pd.read_sql(sql,cnn)
end = time.time()
print(end - start)

这需要 6.35 秒

我也尝试过使用 pymssql:

import pymssql
conn = pymssql.connect(server='s001111', database='XX')  
start = time.time()
data=pd.read_sql(sql,conn)
end = time.time()
print(end - start)

这需要 38.3 秒!

真正的查询需要读取一个维度为 220.000 行 x 353 列的表并应用过滤器(与 where)。

我只需要从数据库中提取数据。

有没有办法在 Python 2.7 中更快地做到这一点?

我找到了pyodbc-memory usage relation caused by SQL Server,但我猜如果这是一个 SQL 问题,在 R 中也会做同样的事情,不是吗?

我也发现了这个:IOPro 但它不是免费的!

此时我想知道问题是 ODBC 连接还是 pandas 本身,所以我尝试了:

cur = conn.cursor();
start = time.time()
cur.execute(sql);
tabla=cur.fetchall() 
end = time.time()
print(end - start) 

但花了 29.29 秒。

那么,仍然:R 从 SQL Microsoft DB 检索数据怎么可能比 Python 快得多?

【问题讨论】:

性能可能很大程度上取决于您使用的驱动程序。我建议尝试另一个驱动程序,看看它是否表现更好。例如,替代方案是pymssql (pypi.python.org/pypi/pymssql/2.1.1)。另请参阅此处的列表:docs.sqlalchemy.org/en/rel_1_0/dialects/mssql.html 进一步,小提示:read_frame 已弃用,您应该改用pd.read_sql。我还建议使用SQLAlchemy 来指定连接(但这与您使用的驱动程序无关)。见pandas.pydata.org/pandas-docs/stable/io.html#sql-queries @joris 谢谢!我已经用 conda pymssql 下载了。还写了代码并运行它。如何测量需要每个库的时间?我认为它仍然比 R 代码花费更多的时间......这可能吗? 这当然是可能的。如果您使用的是 IPython,您可以使用 %time(例如 %time pd.read_sql(...))计算命令所需的时间 如果你想测试问题是pyodbc还是pandas本身,你可以通过计时cur = conn.cursor(); cur.execute(sql); cur.fetchall()来计时查询本身需要多长时间,并将它与使用pandas获取此查询的时间进行比较 【参考方案1】:

RODBC 和 pyodbc 可能会花费大部分时间将数据从数据库服务器传输到您用来运行查询的本地计算机。这里一个非常重要的参数是每个 fetch 循环从数据库服务器移动到本地计算机的行数。 RODBC 和 pyodbc 都允许您配置此参数。

现在,如果你想比较苹果和苹果:

    使用相同的基础架构:相同的远程数据库、相同的本地客户端、相同的网络 使用相同的 ODBC 层:相同的驱动程序管理器、相同的驱动程序、相同的 DSN 使用 R 和 python 为每个 fetch 循环完全检索相同数量的行。 注意:如果您什么都不说,RODBC 的 sqlQuery() 将一次获取 100 行!

我确实使用这种方法将 RODBC 和 pyodbc 与三个不同的数据库(不包括 SQL Server)进行了比较,我总是发现性能具有可比性。

这里是 R 代码:

library(RODBC)
ch <- odbcConnect("DWN",uid="xyz",pwd="xyz",rows_at_time=1024);
ds <- sqlQuery(ch,"select * from large_table limit 100000");

这里有python代码:

>>> import pyodbc
>>> ch = pyodbc.connect('DSN=xyz;UID=xyz;PWD=xyz')
>>> curs = ch.cursor()
>>> curs.execute("select * from large_table limit 100000")
>>> while True:
...      rows = curs.fetchmany(1024)
...      if not rows:
...          break
... 
>>> 

【讨论】:

以上是关于Python 2.7 pyodbc 或 pymssql 与 R RODBC的主要内容,如果未能解决你的问题,请参考以下文章

Linux Python 2.7 odbc连接到Progress Open Edge DB

将pyodbc游标结果输出为python字典

使用 pyodbc 将 Python 连接到 MS SQL Server

在 64 位 PC 上找不到数据源名称的 pyodbc 错误或没有默认驱动程序

使用 pyodbc 将 docker python 连接到 SQL 服务器

使用 Python/pyodbc 插入 Access DB