MySQL 并列写作。如何使用 Python mysql.connector 将流条目写入 MySQL 数据库中的 100 个不同的表

Parallel writing in MySQL. How to write streaming entries to 100 different tables in MySQL database using Python mysql.connector

我想知道如何以并行方式将流数据写入不同的 MySQL 表?

我有以下代码:其中 GetStreaming() returns 元组列表 [(tbName,data1,data2),(tbName,data1,data2),...] 在调用时可用。

import mysql.connector
from pathos.multiprocessing import ProcessingPool as Pool
def foo(tb1,d1,d2):
   global cursor
   stmt = lambda tb1: "INSERT INTO {:} (col1,col2) VALUES (%s, %s)".format(tb1)
   cursor.execute(stmt(tb1), (d1,d2))
if __name=="__main__":
   cnx = mysql.connector.connect(**config) 
   cursor = cnx.cursor()
   for _ in range(int(1e5)):
      data = GetStreaming()
      with Pool() as p:
         p.map(foo, data)
      cnx.commit()
   cursor.close()
   cnx.close()

如果我用普通的 for 循环替换 with Pool() as p: p.map(foo, data)

for each in data:
   foo(each)

代码可以运行。但是,使用多处理方式,我不能再这样做了。我尝试了多种方法,但出现 mysql disconnect or not picklable.

之类的错误

每个“并行”插入过程都需要自己的连接器和光标。您不能在任何类型的线程中共享它们。

您可以使用connection pooling来加快连接的分配和释放。

MySQL(或任何成本低于小国 GDP 的 DBMS)并没有什么神奇之处可以让它扩展到同时处理大约 100 个连接上的大规模数据插入。矛盾的是,更多的连接可能比更少的连接具有更低的吞吐量,因为它们之间存在竞争。您可能需要重新考虑您的系统架构,以便通过一些连接使其正常工作。

换句话说:更少的大表比许多小表性能更好。

最后,阅读有关加速批量插入的方法。例如这种多行插入

INSERT INTO tbl (a,b) VALUES (
  (1,2),
  (3,4),
  (5,6) );

将 运行 比三个连续插入快将近三倍

INSERT INTO tbl (a,b) VALUES (1,2);
INSERT INTO tbl (a,b) VALUES (3,4);
INSERT INTO tbl (a,b) VALUES (5,6);

除非你这样做:

START TRANSACTION;
INSERT INTO tbl (a,b) VALUES (1,2);
INSERT INTO tbl (a,b) VALUES (3,4);
INSERT INTO tbl (a,b) VALUES (5,6);
COMMIT;

因为插入的艰苦工作发生在 COMMIT 时间。对于许多现实世界的用例,我的经验表明大约 100 行的块工作得很好。

插入速度的黄金标准是LOAD DATA INFILE。不过,要使其正常工作,您需要将数据保存在 csv 或类似 csv 的文件中。