簡體   English   中英

sqlalchemy批量插入比構建原始SQL慢

[英]sqlalchemy bulk insert is slower than building raw SQL

我將通過這篇文章對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

這個原始SQL的插入是這樣的:

MySession.execute('''
insert into MyTable (e, l, a)
values {}
'''.format(",".join(my_insert_str)))

使用這種方法,我在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

.......

        dict_list = []
        for i, row in chunk.iterrows():

            dict_list += [{"e" : row["e"], "l" : l, "a" : a}]

        MySession.execute(
            Myclass.__table__.insert(),
            dict_list
        )

這是我連接數據庫的方式。

    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)

我的設置是否存在使性能大大降低的問題? 我嘗試使用其他數據庫驅動程序-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

我正在連接MS SQL Server2008。如果我錯過任何其他詳細信息,請告訴我。

原始SQL方法的問題在於它不是SQL注入安全的。 因此,或者,如果您對如何解決此問題有任何建議,它也會非常有用:)。

你在做

MySession.execute(
    Myclass.__table__.insert(),
    dict_list
)

使用executemany() 它與INSERT INTO ... VALUES ... 要使用VALUES ,請執行以下操作:

MySession.execute(
    Myclass.__table__.insert().values(dict_list)
)

附帶說明,SQL注入問題使用參數解決:

MySession.execute('''
insert into MyTable (e, l, a)
values (?, ?, ?), (?, ?, ?), ...
''', params)

這里的要點是您沒有比較等效的構造。 您沒有在SQLAlchemy生成的查詢中使用VALUES ,但是在文本SQL中,並且在文本SQL中未使用參數化,但是在SQLAlchemy生成的查詢中。 如果為執行的SQL語句打開日志記錄,您將看到完全不同的地方。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM