【问题标题】:Is buffering commits in MySQL/PyMySQL a viable alternative to inserting multiple rows at once?在 MySQL/PyMySQL 中缓冲提交是否是一次插入多行的可行替代方案?
【发布时间】:2018-07-01 09:14:30
【问题描述】:

我正在开发一个涉及不断插入 MySQL 数据库的数据收集应用程序。我正在使用 Python 和 PyMySQL 来完成此任务。我需要每秒在主表中插入大约 100 行。 python 进程不断运行并保持与位于远程服务器上的 MySQL 数据库的持续连接。

我知道,一般来说,最好将数据作为缓冲区插入(一次多行),而不是单独插入。每 100 次左右的插入进行提交(PyMySQL 中的connection.commit())是否会实现与一次插入大量数据相同的开销减少?

出于语法原因,将行插入分成单独的操作更容易。

【问题讨论】:

  • 您是在谈论在事务上下文中执行此操作吗?如果没有,大多数驱动程序都会设置自动提交,因此每个语句都会自动提交,并且显式提交调用是多余的。您可以使用“multi-INSERT”来执行此操作,或者如果速度是最重要的问题,则可以使用 LOAD DATA INFILE 从文件中读取数据。

标签: python mysql pymysql


【解决方案1】:

应该发现远程服务器的最大开销不是处理时间,而是每个查询发送到服务器并返回响应的往返时间......如果服务器距离超过 ~10 毫秒,单独插入 100 行/秒是不可能的,因为在网络上浪费了太多时间,等待。

有一些内部原因使批量插入或不频繁提交的性能更好,但当服务器距离较远时,这些原因变得越来越不相关。从您的角度来看,单个插入总是比批量插入慢,这仅仅是因为往返次数。

在服务器本身,批量插入带来了一个小优势......在事务中,在每个 n 插入之后提交将带来一个小优势......但同样在性能上的任何差异使用这些策略将消失在远程连接的噪音中。

简而言之,在单个查询而不是多个查询中插入多行是您可以做出的唯一有意义的改进,因为服务器性能不是您的主要问题,而是距离。

当然,如果出于某种原因需要单独的插入查询,那么在程序中使用多个线程和与数据库的多个连接是提高性能的一种可能策略,因为 n连接可以并行执行 n 个查询,从而将往返时间 t 的净实际影响降低到接近 t / n .

【讨论】:

    猜你喜欢
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    • 2017-11-29
    • 2013-01-26
    相关资源
    最近更新 更多