【问题标题】:pyodbc executemany is not batching insert - SQL server insert is very slowpyodbc executemany 没有批量插入 - SQL 服务器插入非常慢
【发布时间】:2018-05-15 22:22:30
【问题描述】:

我有一个从本地日志读取的应用程序,该日志由每行上的 JSON 对象组成。它解析每一行并尝试插入到 SQL 服务器数据库。 SQL 服务器作为 PaaS 产品在 Azure 中运行。

我在 DB 上删除了外键以加快插入速度,但性能非常慢。

我在 python 中进行了分析,发现如下。注意执行调用,每个调用需要 60 毫秒。

Mon May 14 20:05:05 2018    logparserprof.out

         385055 function calls (384911 primitive calls) in 1832.423 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     11/1    0.000    0.000 1832.423 1832.423 {built-in method builtins.exec}
        1    0.000    0.000 1832.423 1832.423 logparsers.py:1(<module>)
        1    0.212    0.212 1831.728 1831.728 logparsers.py:282(parse)
    12796    0.030    0.000 1816.892    0.142 logparsers.py:240(parse_event)
    30432 1814.571    0.060 1814.571    0.060 {method 'execute' of 'pyodbc.Cursor' objects}
    12471    0.014    0.000 1796.979    0.144 logparsers.py:232(parse_event_Task)

所以我决定批量请求并看到executemany 调用并以相似的速度再次运行。 (我尝试每插入 1000-1500 条记录进行批处理)

我再次分析,executemany 花了 46 秒!

Tue May 15 00:55:46 2018    logparserprof2.out

         384660 function calls (384516 primitive calls) in 1659.800 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       35 1635.272   46.722 1635.272   46.722 {method 'executemany' of 'pyodbc.Cursor' objects}
      335   20.095    0.060   20.095    0.060 {method 'execute' of 'pyodbc.Cursor' objects}

我查看了 Windows 中的 resmon 以检查网络延迟,发现平均为 57-60 毫秒。

我的下一步是尝试执行多线程并尽可能为应用程序添加并行性以进行插入。但是,我想知道批量/批量插入是否可以做得更好。

我了解 MS SQL 服务器批量插入适用于 CSV 文件,这些文件必须在本地或通过 CIFS/SMB..etc 访问。

编辑 删除了关于 executemany 是简单循环的链接,因为它来自 pymssql 而不是 pyodbc。

【问题讨论】:

  • 您问题中的链接指向 pymssql 代码,而不是 pyodbc 代码。 pymssql 和 pyodbc 是不同的产品。看来您确实在使用 pyodbc,但是您使用的是最新版本(当前为 4.0.23)以及fast_executemany = True?
  • @GordThompson 我明白了,谢谢。是的,我使用的是最新的,我将 fast_executemany 设置为 True,但插入速度非常慢。
  • 查看您的实际代码可能会有所帮助。
  • 是否可以让 SQL Profiler 向您展示服务器上发生的情况?使用fast_executemany = False,您应该看到每个插入的单独sp_prepexec 调用,但使用fast_executemany = True,您应该看到一个sp_prepare,后跟多个sp_execute 调用。
  • @GordThompson 任何想法如何获取 SQL 分析器?这是 Azure 中的 SQL DB PaaS 产品。

标签: python sql-server pyodbc


【解决方案1】:

这是真的:executemany 不会为 pyodbc 批量插入。您可以使用多值插入或调用 bcp 作为 shell 命令。希望,它将在最近的将来修复。插入速度还取决于表结构和底层硬件。

【讨论】:

  • 当我将 fast_executemany 设置为 True 后,您现在确定这一点了吗?它运行得很快,解决了我的问题?
  • “executemany 不会为 pyodbc 批量插入” - 对于当前版本的 pyodbc 和 Microsoft 的“用于 SQL Server 的 ODBC 驱动程序 x”,fast_executemany = True 确实启用了批处理使用 ODBC 参数数组插入。
猜你喜欢
  • 2011-08-07
  • 1970-01-01
  • 2019-09-29
  • 1970-01-01
  • 2020-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-28
相关资源
最近更新 更多