2011-04-17 171 views
17

利用这种表:pyodbc - 非常缓慢的批量插入速度

CREATE TABLE test_insert (
    col1 INT, 
    col2 VARCHAR(10), 
    col3 DATE 
) 

以下代码需要40秒,以运行:

import pyodbc 

from datetime import date 


conn = pyodbc.connect('DRIVER={SQL Server Native Client 10.0};' 
    'SERVER=localhost;DATABASE=test;UID=xxx;PWD=yyy') 

rows = [] 
row = [1, 'abc', date.today()] 
for i in range(10000): 
    rows.append(row) 

cursor = conn.cursor() 
cursor.executemany('INSERT INTO test_insert VALUES (?, ?, ?)', rows) 

conn.commit() 

与psycopg2等效代码只需要3秒。我不认为mssql比postgresql慢得多。使用pyodbc时如何提高批量插入速度的想法?

编辑:添加一些注意事项如下ghoerz的发现

在pyodbc的executemany的流程是:

  • 准备发言
  • 回路每组参数
    • 绑定集参数
    • 执行

在ceODBC的executemany的流程是:

  • 准备发言
  • 绑定的所有参数
  • 执行
+0

尝试使用显式事务。 – 2011-04-17 13:55:48

+0

阅读http://stackoverflow.com/questions/1063770/in-python-using-pyodbc-how-do-you-perform-transactions,它似乎并不像pyodbc支持显式事务。 – sayap 2011-04-17 14:26:04

+0

这不是我读它的方式。您关闭自动提交,并且必须显式调用回滚或提交。但是,我不知道它是否有所作为,但是我会尝试自己。 – 2011-04-17 15:31:48

回答

7

我是有pyODBC插入一个类似的问题SQL Server 2008数据库使用executemany()。当我在SQL端运行探查器跟踪时,pyODBC正在创建一个连接,准备参数化插入语句,并为其执行一行。然后,它将无可争辩地将该声明关闭,并关闭连接。然后它为每一行重复这个过程。

我无法在pyODBC中找到任何解决方案,但没有这样做。我结束了切换到ceodBC连接到SQL Server,它正确地使用参数化语句。

+0

感谢您的确认和提示。我已将此作为http://code.google.com/p/pyodbc/issues/detail?id=250提交 – sayap 2012-03-29 23:33:46

3

尝试ceODBC和mxODBC,两者也痛苦缓慢。在http://www.ecp.cc/pyado.html的帮助下完成了adodb连接。总运行时间提高了6倍!

comConn = win32com.client.Dispatch(r'ADODB.Connection') 
DSN = 'PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=%s%s' %(dbDIR,dbOut) 
comConn.Open(DSN) 

rs = win32com.client.Dispatch(r'ADODB.Recordset') 
rs.Open('[' + tblName +']', comConn, 1, 3) 

for f in values: 
    rs.AddNew(fldLST, f) 

rs.Update() 
0

我在使用pypyODBC w/python 3.5和Microsoft SQL Server Management Studio。 使用pypyodbc的.executemany()方法,一个特定的表(〜70K行w/40个变量)需要112秒的时间才能进行INSERT。

随着ceODBC它花了4秒钟。

1

我将数据写入文本文件,然后调用BCP实用程序。快得多。从大约20到30分钟到几秒钟。

2

pyodbc 4.0.19添加了Cursor#fast_executemany选项来帮助解决此问题。详情请参阅this answer