Ant*_*lev 2 python sql-server performance bulkinsert sqlalchemy
我将通过这篇文章对SQLAlchemy的批量插入性能.我尝试了基准测试中指定的各种方法 - SQLAlchemy ORM bulk_insert_mappings(), SQLAlchemy Core. 不幸的是,插入1000行所有这些方法需要大约1分钟来插入它们.这非常缓慢.我也尝试了这里指定的方法- 这需要我构建一个大的SQL语句,如:
INSERT INTO mytable (col1, col2, col3)
VALUES (1,2,3), (4,5,6) ..... --- up to 1000 of these
Run Code Online (Sandbox Code Playgroud)
这个原始SQL的插入类似于:
MySession.execute('''
insert into MyTable (e, l, a)
values {}
'''.format(",".join(my_insert_str)))
Run Code Online (Sandbox Code Playgroud)
使用这种方法,我在10-11秒内将性能提高了50倍+次,达到10000次插入.
以下是使用内置库的方法的代码.
class MyClass(Base):
__tablename__ = "MyTable"
e = Column(String(256), primary_key=True)
l = Column(String(6))
a = Column(String(20), primary_key=True)
def __repr__(self):
return self.e + " " + self.a+ " " + self.l
Run Code Online (Sandbox Code Playgroud)
.......
dict_list = []
for i, row in chunk.iterrows():
dict_list += [{"e" : row["e"], "l" : l, "a" : a}]
MySession.execute(
Myclass.__table__.insert(),
dict_list
)
Run Code Online (Sandbox Code Playgroud)
这是我连接数据库的方式.
params = urllib.quote_plus("DRIVER={SQL Server Native Client 10.0};SERVER=servername;DATABASE=dbname;UID=user;PWD=pass")
engine = create_engine("mssql+pyodbc:///?odbc_connect=%s" % params )
MySession.configure(bind=engine, autoflush=False, expire_on_commit=False)
Run Code Online (Sandbox Code Playgroud)
我的设置是否存在降低性能的问题?我试过不同的db驱动程序 - pyodbc和pymssql.我试过什么我不能接近他们在文章中声称的数字:
SQLAlchemy ORM: Total time for 100000 records 2.192882061 secs
SQLAlchemy ORM pk given: Total time for 100000 records 1.41679310799 secs
SQLAlchemy ORM bulk_save_objects(): Total time for 100000 records 0.494568824768 secs
SQLAlchemy ORM bulk_insert_mappings(): Total time for 100000 records 0.325763940811 secs
SQLAlchemy Core: Total time for 100000 records 0.239127874374 secs
sqlite3: Total time for 100000 records 0.124729156494 sec
Run Code Online (Sandbox Code Playgroud)
我正在连接到MS SQL Server 2008.如果我错过了任何其他细节,请告诉我.
原始SQL方法的问题在于它不是SQL注入安全的.所以,如果您有如何解决这个问题的建议,它也将非常有帮助:).
你在做
MySession.execute(
Myclass.__table__.insert(),
dict_list
)
Run Code Online (Sandbox Code Playgroud)
哪个使用executemany().它不一样INSERT INTO ... VALUES ....要使用VALUES,请执行:
MySession.execute(
Myclass.__table__.insert().values(dict_list)
)
Run Code Online (Sandbox Code Playgroud)
作为旁注,SQL注入问题使用参数解决:
MySession.execute('''
insert into MyTable (e, l, a)
values (?, ?, ?), (?, ?, ?), ...
''', params)
Run Code Online (Sandbox Code Playgroud)
这里要说的是你没有比较等效的结构.您没有VALUES在SQLAlchemy生成的查询中使用,但是您在文本SQL中,并且您没有在文本SQL中使用参数化,但是您在SQLAlchemy生成的查询中.如果打开已执行SQL语句的日志记录,您将看到确切的不同之处.
| 归档时间: |
|
| 查看次数: |
2870 次 |
| 最近记录: |