当前位置: 首页 > 面试题库 >

导入前后的InnoDB索引

晁砚
2023-03-14
问题内容

我正在尝试为InnoDB表导入mysqldump生成的大型SQL文件,但是即使在调整my.cnf中的某些参数并禁用了AUTOCOMMIT(以及FOREIGN_KEY_CHECKS和UNIQUE_CHECKS之后,也要花很长时间),但是该表确实没有任何外来或唯一键)。但是我想知道是否由于表中的多个索引花费了这么长时间。

查看SQL文件,似乎在插入所有数据之前在CREATE
TABLE语句中创建了索引。根据我的(有限的)研究和个人经验,我发现插入所有数据后添加索引的速度更快。是否不必检查每个INSERT的索引?我知道mysqldump确实有一个--disable- keys选项,它确实可以在插入之前禁用密钥,但是显然这仅适用于MyISAM表而不适用于InnoDB。

但是,为什么mysqldump不能在InnoDB表的CREATE TABLE语句中不包含键,然后在插入所有数据之后执行ALTER
TABLE?还是InnoDB的工作方式不同,并且没有速度差异?

谢谢!


问题答案:

我在过去的工作中对这个概念进行了一些试验,我们需要一种在MySQL服务器之间复制架构的快速方法。

当您插入具有二级索引的表时,确实存在性能开销。插入需要更新聚簇索引(又名表),也需要更新二级索引。一个表具有的索引越多,它导致插入的开销就越大。

InnoDB具有称为更改缓冲区的功能,该功能可以通过延迟索引更新来有所帮助,但最终必须将它们合并。

插入没有辅助索引的表的速度更快,因此很容易尝试将索引的创建推迟到数据加载后再进行,正如您所描述的那样。

Percona Server是MySQL的一个分支,尝试了一个mysqldump --optimize- keys选项。当您使用此选项时,它会将mysqldump的输出更改为不带索引的CREATE TABLE,然后插入所有数据,然后在数据加载后添加ALTER
TABLE以添加索引。参见https://www.percona.com/doc/percona-
server/LATEST/management/innodb_expanded_fast_index_creation.html

但是以我的经验来看,性能的净改善很小。即使没有索引的表也要花很多时间才能插入很多行。然后,还原需要运行ALTER
TABLE来建立索引。一张大桌子要花一些时间。当您计算INSERT的时间加上建立索引的额外时间时,它比将传统方法插入具有索引的表中仅快百分之几(低个位数)。

创建这种后处理索引的另一个好处是索引的存储更加紧凑,因此,如果需要节省磁盘空间,这是使用此技术的更好理由。

我发现通过 并行加载多个表 对性能进行恢复更有利。

  • 新的MySQL 8.0工具mysqlpump支持多线程转储。
  • 开源工具mydumper支持多线程转储,并且还具有一个名为的多线程还原工具myloader。mydumper / myloader的最糟糕的缺点是该文档实际上不存在,因此您必须是一个勇敢的超级用户才能弄清楚如何运行它。

另一种策略是使用mysqldump --tab转储CSV文件而不是SQL脚本。批量加载CSV文件比执行SQL脚本还原数据要快得多。好吧,它转储用于表定义的SQL文件和用于导入数据的CSV文件。它为每个表创建单独的文件。您必须通过加载所有SQL文件(这是快速的)来手动重新创建表,然后使用mysqlimport加载CSV数据文件。mysqlimport工具甚至还有一个--use- threads用于并行执行的选项。

使用不同数量的并行线程仔细测试。我的经验是4个线程是最好的。随着更大的并行度,InnoDB成为瓶颈。但是,您的体验可能会有所不同,具体取决于MySQL的版本和服务器硬件的性能。

最快的还原方法是使用物理备份工具时,最流行的还原方法是Percona
XtraBackup。这样可以实现快速备份甚至更快的还原。实际上,已备份的文件已准备就绪,可以复制到位并用作活动表空间文件。缺点是您必须关闭MySQL服务器才能执行还原。



 类似资料:
  • 关于师父的解释: 关于奴隶的解释: 贷款-l 查询执行时间长。

  • myisam和innodb索引实现的不同 MyIsam:主键索引和普通键索引的树的叶子节点和非叶子节点存放的数据是一样的,非叶子节点存放的都是主键,叶子节点存放的都是主键和相应的地址值,地址值根据另外一个表.MYD查找数据 主键索引:叶子节点为全部数据的K和对应的V的地址,非叶子节点存放的是带有索引的K 辅助索引:和主键索引一样 Innodb:主键索引的叶子节点存放的是所有数据的key和全部数据,

  • 我正在努力做到以下几点: 从keras.wrappers.scikit_学习导入KerasClassifier 但是我得到了错误: 文件“”,第1行,在from keras.wrappers.scikit\u中学习导入KerasClassifier 文件“/opt/anaconda3/lib/python3.7/site packages/keras/init.py”,第3行,在from中。导入U

  • 我目前正在通过webpack/babel在React应用程序中使用ES6。我使用索引文件收集模块的所有组件并将其导出。不幸的是,这看起来是这样的: 所以我可以很好地从其他地方导入它,比如: 显然,这不是一个很好的解决方案,所以我想知道,是否还有其他方法。我似乎无法直接导出导入的组件。

  • 我已经创建了一个spring boot后端和一个angular前端,现在我想使用sprint boot在8080上运行,其主页显示索引。html(来自angular)。 我已经使用ng build--prod命令在angular中创建了dist文件夹,并将其复制到(src/main/resources/static)文件夹中。在此处输入图像描述 除此之外,我读了很多关于这个的stackoverfl

  • 在插入之前,你想通过一段 SQL 为你的 POJO 某一个字段设值。你可以通过 @Prev 属性 @Table("t_pet") public class Pet{ @Name private String name; @Column("photo") @Prev( @SQL("SELECT txt FROM t_pet_photo WHERE pname=@n