【问题标题】:Improving SQL Performance: Many times insert or update multiple table提高 SQL 性能:多次插入或更新多个表
【发布时间】:2021-08-23 07:32:28
【问题描述】:

excel大数据导入MySQL数据库耗时较长,如何提高性能?

Excel 数据如下:

sheet_student

id name status course_id
1001 alpha 0 C001
1002 alpha 1 C002
1003 alpha 0 C003
... ... ... ...
1501 zip 0 C399

sheet_course

course_id course_code course_qulity
C001 computer science 99
C001 computer vision 86
C001 computer network 87
C001 database 91
C002 math 92
C002 logical 93
C002 ai 94
... ... ...
C299 computer vision 94

MySQL 喜欢的表如下:

学生桌

id name status course_id
primary key string int string
CREATE TABLE IF NOT EXISTS `student`(
   `id` INT UNSIGNED AUTO_INCREMENT,
   `name` VARCHAR(100) NOT NULL,
   `status` INT,
   `course_id` INT NOT NULL,
   PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

源表

id reference_id course_code course_qulity
primary key reference for student table primary key string int
CREATE TABLE IF NOT EXISTS `course`(
   `id` INT UNSIGNED AUTO_INCREMENT,
   `reference_id` INT UNSIGNED,
   `course_code` VARCHAR(100) NOT NULL,
   `course_qulity` INT NOT NULL,
   PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

导入过程可以这样描述:

图像的浅灰色区域可能会有所改善,但我不知道如何优化它。 用inner join查询学生表和课程表是个不错的方法。但是insertupdate操作不行。

当excel数据太大时,导入过程会很耗时。

更新

同一个excel多次导入时,MySQL的数据会根据excel数据进行更新。 student 表中的namecourse_id 字段确定行数据是否唯一。 course 表中的reference_idcourse_code 字段确定行数据是否唯一。

【问题讨论】:

  • 提供紧凑的 Excel 示例数据(每表 3-5 行)、MySQL 初始数据(结构为 CREATE TABLE,如果导入前存在的数据可能会影响,则某些行为 INSERT INTO)和完整的最终此源数据导入后的 MySQL 表数据状态,并附有详细说明。
  • 何不尝试一下,看看会发生什么?
  • 您是否在 VBA 中使用循环从数据库中选择行来决定更新或插入?如果是这样,一个解决方案可能是创建两个表 student_new_data 和 course_new_data ,导入完整的 Excel 列表,然后使用 MySQL 的 INSERT ON DUPLICATE KEY UPDATE 一次用于学生,一次用于课程以一步更新整个原始表。跨度>
  • @ThorstenKettner 感谢您为我提供解决方案。

标签: mysql sql database-performance


【解决方案1】:

当单个语句可用于对整个表(或表的子集)执行某些操作时,数据库的运行速度会快得多。一次做一行是很慢的。两个批处理 IODKU 语句可以替换您的流程图。

  1. 将每个 Excel 工作表转储到 CSV 文件中。
  2. 将每个 CSV 加载到 MySQL 中的临时表中。
  3. 使用批处理操作来清理数据(如有必要)。
  4. 使用批处理操作将数据复制到真实表中。

第 4 步中的“批处理”是指

INSERT INTO ... SELECT ... FROM ...;

或(正如托尔斯坦所说)

INSERT INTO ... SELECT ... FROM ...
    ON DUPLICATE KEY UPDATE ...;

或者有时,两步过程here 会很有用。

【讨论】:

    【解决方案2】:

    加快导入/插入/更新的一些想法:

    • 删除现有索引 - 添加越来越多的索引后,将数据插入 MySQL 表的速度会变慢。因此,如果您要将数据加载到新表中,最好将其加载到没有任何索引的表中,然后在加载数据后才创建索引。

    • 批量插入数据 - 为了优化插入速度,将许多小操作组合成一个大操作。理想情况下,您建立一个连接,一次发送许多新行的数据,并将所有索引更新和一致性检查延迟到最后。实际上,您可以使用以下查询结构在每个 INSERT 语句中插入一组记录,例如 1000 条记录,而不是一次执行一条记录:

      INSERT INTO table_name (column_list) VALUES (value1, value2) (value1, value2), ... (value1, value2);

    • 从附近位置加载数据 - 如果您要向远程服务器加载 GB 或 TB 的数据,请记住,无论将记录实际插入数据库需要多长时间,您的 SQL 客户端需要将该数据传输到该服务器。因此,网络可能是一个重要的瓶颈。此外,对于大型 SQL 转储,在每个插入(或插入组)上打开和关闭连接可能会占用大量时间。 因此,理想情况下,您应该将文件传输到数据库服务器一次,然后从本地文件系统加载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-14
      • 1970-01-01
      • 1970-01-01
      • 2014-06-10
      • 2011-12-20
      • 1970-01-01
      相关资源
      最近更新 更多