MySQL优化INSERT速度因索引而变慢

2024-04-16

MySQL 文档 http://dev.mysql.com/doc/refman/5.0/en/insert-speed.html say :

假设 B 树索引,表的大小会使索引的插入速度减慢 log N。

这是否意味着对于每个新行的插入,插入速度将减慢 log N 倍,其中 N,我假设是行数?即使我在一个查询中插入所有行? IE。 :

INSERT INTO mytable VALUES (1,1,1), (2,2,2),  (3,3,3), .... ,(n,n,n)

其中 n 约为 70,000

目前,我的表中有约 147 万行,其结构如下:

CREATE TABLE mytable (
   `id` INT,
   `value` MEDIUMINT(5),
   `date` DATE,
   PRIMARY_KEY(`id`,`date`)
) ENGINE = InnoDB

当我以上述方式插入事务时,提交时间约为 275 秒。我该如何优化这一点,因为每天都会添加新数据,并且插入时间只会不断减慢。

另外,除了查询之外,还有什么可能有帮助的吗?也许一些配置设置?

可能的方法 1 - 删除索引

我读到在插入之前删除索引可能有助于插入速度。插入后,我再次添加索引。但这里唯一的索引是主键,在我看来,删除它并没有多大帮助。另外,虽然主键是dropped,所有选择查询都会变得非常慢。

I do not know of any other possible methods.

Edit :以下是在大约 147 万行的表中插入大约 60,000 行的一些测试:

使用上述简单查询:146秒

使用 MySQL 的 LOAD DATA infile :145秒

按照 David Jashi 在他的回答中的建议,使用 MySQL 的 LOAD DATA infile 并拆分 csv 文件:60 个文件(每个 1000 行)需要 136 秒,6 个文件(每个文件 10,000 行)需要 136 秒

删除并重新添加主键:键删除花费了 11 秒,插入数据花费了 0.8 秒,但重新添加主键花费了 153 秒,总共花费了约 165 秒


如果您想要快速插入,首先需要的是合适的硬件。这需要足够的 RAM、SSD(而不是机械驱动器)和相当强大的 CPU。

既然你使用 InnoDB,你想要的是优化它,因为默认配置是为慢速和旧机器设计的。

这是关于配置 InnoDB 的精彩读物 https://www.percona.com/blog/2007/11/01/innodb-performance-optimization-basics/

之后,您需要了解一件事 - 这就是数据库如何在内部完成其工作,硬盘驱动器如何工作等等。我将在下面的描述中简化该机制:

事务是MySQL等待硬盘确认其写入数据的过程。这就是为什么机械驱动器上的事务处理速度很慢,它们每秒可以执行 200-400 个输入输出操作。换言之,这意味着您可以在机械驱动器上使用 InnoDB 每秒进行 200 次左右的插入查询。自然,这是简化的解释,只是为了概述正在发生的事情,这不是交易背后的完整机制.

由于查询(尤其是与表大小相对应的查询)在字节方面相对较小 - 您实际上在单个查询上浪费了宝贵的 IOPS。

如果您将多个查询(100 或 200 或更多,没有确切的数字,您必须测试)包装在单个事务中,然后提交它 - 您将立即实现每秒更多的写入。

Percona 人员在相对便宜的硬件上实现了每秒 15k 次插入。即使每秒 5k 插入也不错。像你这样的表很小,我已经对类似的表(多了 3 列)进行了测试,并且使用 16GB RAM 机器和 240GB SSD(1 个驱动器,无 RAID,用于测试目的)。

TL;DR: - 按照上面的链接,配置您的服务器,获取 SSD,将多个插入包含在 1 个事务中并获利。并且不要关闭然后再打开索引,它并不总是适用,因为在某些时候您将花费处理和 IO 时间来构建它们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL优化INSERT速度因索引而变慢 的相关文章

  • PHP数组转SQL

    array array 53 gt array num gt 20 name gt aaa 10 gt array num gt 20 name gt bbb sql 插入数据 id num name 值 53 20 aaa 10 20 b
  • 通过php在csv单元格中创建回车符

    我正在尝试动态生成一个 csv 文件 其中包含一些包含多行的单元格 例如 地址字段需要分组为单个 地址 单元格 而不是地址 城市 州等 一切进展顺利 但在过去的两天里 我尝试在代码中插入 r r n n chr 10 chr 13 以及回车
  • MySQL 1443:这是什么意思?

    我正在尝试在 MySQL 5 0 中进行以下形式的更新 update mytable myfield t set f blah where t id in select v id from myview v where MySQL 告诉我
  • 我们可以在 Mysql 查询中使用 PHP 函数 strtotime [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有以下 MySQL 语法 这给了我一个错误 我知道你不能直接比较日期变量 所以我使用strtotime创建 Unix 时间戳来比较日
  • 如何计算 MySQL 中日期的平均值?

    如何在 MySQL 中计算日期之间的平均值 我对时间值 小时和分钟更感兴趣 在桌子上有 date one datetime date two datetime 执行如下查询 SELECT AVG date one date two FROM
  • 如何避免MySQL'尝试获取锁时发现死锁;尝试重新启动交易'

    我有一个innoDB表 记录在线用户 它会在用户每次刷新页面时进行更新 以跟踪他们所在的页面以及他们上次访问该网站的日期 然后我有一个每 15 分钟运行一次的 cron 来删除旧记录 我收到 尝试获取锁定时发现死锁 昨晚尝试重新启动事务大约
  • Docker 应用程序更新后无法连接到数据库

    在我的公司 我有一个旧的 Symfony 应用程序在 Docker 容器中运行 该应用程序连接到一个 SQL 数据库 该数据库也在 Docker 容器内运行 该图像是使用 php 7 2 apache stretch 构建的 但该版本已不再
  • 带有多表查询的 SQL Join 版本的 Djangoviews.py

    需要一些有关 Django 版本的 SQL 多表查询的帮助 该查询使用 3 个表来检索餐厅名称 地址Restaurants table和美食类型来自Cuisinetypes table 所有这些都基于通过 URL 传递的菜品名称 菜品 ID
  • SQL 错误:1452:无法添加或更新子行:外键约束失败

    我的数据库中有两个表 order course order有一个专栏courseid哪个参考列id of the course桌子 每当我尝试做的时候saveAll in CakePHP以上SQL将显示错误并且不会保存数据 听起来是在数据库
  • 在日期 presto SQL 上运行总和

    我正在尝试使用 Presto SQL 根据下面的示例数据计算某个日期内 t 列和 s 列的累积总和 Date T S 1 2 19 2 5 2 1 19 5 1 3 1 19 1 1 我想得到 Date T S cum T cum S 1
  • 如何插入显式值和从另一个表检索的数据的混合

    我知道两种将数据插入表的方法 方法1 显式值 INSERT INTO table field1 field2 field3 VALUES value1 value2 value3 方法2 从另一个表复制数据 INSERT INTO tabl
  • 数据库索引:是好事、坏事还是浪费时间?

    这里通常建议添加索引作为性能问题的补救措施 我只讨论读取和查询 我们都知道索引会使写入速度变慢 多年来 我在 DB2 和 MSSQL 上多次尝试过这种补救措施 但结果总是令人失望 我的发现是 无论索引会让事情变得更好是多么 明显 事实证明查
  • 更改 django 应用程序名称时迁移历史记录不一致

    我正在尝试重命名 django 网站中的应用程序之一 还有另一个应用程序依赖于它及其 mysql 表 我检查了两个应用程序中的所有文件 并将旧名称的实例更改为新名称 但是 现在我在尝试执行迁移时遇到此错误消息 File Users Limo
  • 为每一表行创建一个 json

    我想从表中的数据创建 json 表格看起来像这样 code D5ABX0 MKT536 WAEX44 我正在使用 FOR JSON PATH 这很好 SELECT code FROM feature FOR JSON PATH 但是这个查询
  • 通过 SqlConnection/SqlCeConnection 连接到 .sdf 数据库时出现问题

    我在连接到 sdf sql 紧凑版 数据库时遇到了巨大的麻烦 我可以最初连接以提取行以验证用户名 密码 但是当我尝试通过 SqlCeConnection SqlCeCommand 命令或尝试添加项目 SqlClient SqlCommand
  • 对所有列实施搜索过滤器

    我在 PostgreSQL 中找到了这个搜索示例http www postgresql org docs current interactive textsearch tables html TEXTSEARCH TABLES SEARCH
  • 将 MySQL 与实体框架结合使用 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 在 Google 上找不到任何有关实体框架 MySQL 的信息 所以我希望有人知道 已发布 获取适用于
  • 在 SQL 存储过程中选择并合并表中的行

    有一个具有架构的临时表 ID 序列号 姓名 ID 不唯一SeqNo 整数 可以是 1 2 或 3 以ID SeqNo作为主键排序名称 任何文本 表中的示例数据如下 1 1 RecordA 2 1 RecordB 3 1 RecordC 1
  • MySQL 查询在基于特定标签组合获取行时返回不需要的行

    我在 Windows 8 PC 上运行 PHP MySQL 我有一张桌子mytable像下面这样 product tag lot 1111 101 2 1111 102 5 2222 103 6 3333 104 2 4444 101 2
  • 为什么我们需要带有聚合函数的 GROUP BY?

    我看到一个例子 其中有一个员工列表 表 及其各自的月薪 我对工资进行了汇总 并在输出中看到了完全相同的表格 这很奇怪 这是必须做的 我们必须找出本月我们支付多少员工工资 为此 我们需要在数据库中对他们的工资金额进行求和 如下所示 SELEC

随机推荐