innodb导入前后索引

mkshixfv  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(440)

我正试图导入一个由mysqldump为innodb表生成的大型sql文件,但即使在调整my.cnf中的一些参数并禁用autocommit(以及外部\u键\u检查和唯一\u检查,但该表没有任何外部或唯一键)之后,也需要很长时间。但我想知道是不是因为表中有几个索引,所以花了这么长时间。
查看sql文件,在插入所有数据之前,似乎正在createtable语句中创建索引。根据我(有限的)研究和个人经验,我发现在插入所有数据之后添加索引会更快。它不必检查每个插入的索引吗?我知道mysqldump有一个 --disable-keys 选项-在插入之前禁用键,但显然这只适用于myisam表,而不适用于innodb。
但是为什么mysqldump不能在createtable语句中为innodb表包含键,然后在插入所有数据之后执行altertable呢?或者innodb的工作方式不同,并且没有速度差异?
谢谢!

dced5bon

dced5bon1#

我在过去的一份工作中尝试过这个概念,我们需要一种在mysql服务器之间复制模式的快速方法。
当您插入到具有二级索引的表时,确实存在性能开销。insert需要更新聚集索引(也称为表),还需要更新二级索引。表的索引越多,插入的开销就越大。
innodb有一个名为changebuffer的特性,它通过延迟索引更新来提供一些帮助,但它们最终必须合并。
插入到没有二级索引的表会更快,因此,如您所述,尝试将索引创建推迟到数据加载之后。
mysql的一个分支percona服务器用 mysqldump --optimize-keys 选项。当您使用这个选项时,它会将mysqldump的输出更改为create table without no index,然后插入所有数据,然后alter table在加载数据后添加索引。看到了吗https://www.percona.com/doc/percona-server/latest/management/innodb_expanded_fast_index_creation.html
但以我的经验来看,业绩的净增长很小。插入大量行仍然需要一段时间,即使对于没有索引的表也是如此。然后,还原需要运行alter表来构建索引。一张大table要花点时间。当计算插入时间加上构建索引所需的额外时间时,只比将传统方法插入到具有索引的表中快几个百分点(低个位数)。
这种后处理索引创建的另一个好处是索引存储得更紧凑,因此如果您需要节省磁盘空间,那么使用这种技术是一个更好的理由。
我发现通过并行加载多个表来恢复性能更为有利。
新的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服务器才能执行恢复。

相关问题