我尝试了具有类似数据负载的不同解决方案 - 超过 1B - 但我发现更好的是:
通过一些额外的工作,LOAD DATA INFILE当表有许多索引时,可以使MyISAM 表的运行速度更快。使用以下程序:
执行FLUSH TABLES语句或mysqladmin flush-tables命令。
使用myisamchk --keys-used=0 -rq /path/to/db/tbl_name删除所有使用索引的表。
使用 将数据插入到表中LOAD DATA INFILE。这不会更新任何索引,因此速度非常快。
重新创建索引myisamchk -rq /path/to/db/tbl_name。这会在将索引树写入磁盘之前在内存中创建索引树,这比在 LOAD DATA INFILE 期间更新索引要快得多,因为它避免了大量的磁盘搜索。生成的索引树也是完美平衡的。
执行FLUSH TABLES语句或mysqladmin flush-tables命令。
LOAD DATA INFILE如果您插入数据的 MyISAM 表为空,则自动执行上述优化。自动优化和显式使用过程之间的主要区别在于,您可以让 myisamchk 为索引创建分配比您希望服务器在执行 LOAD DATA INFILE 语句时为索引重新创建分配更多的临时内存。
为了从 myisamchk 获得更好的性能,您必须调整一些参数,例如:
--key_buffer_size --myisam_sort_buffer_size --read_buffer_size --write_buffer_size
Run Code Online (Sandbox Code Playgroud)
取决于您的硬件架构
使用LOCALwith 时LOAD DATA,会在服务器的临时目录中创建文件的副本。这不是tmpdir或slave_load_tmpdir的值决定的目录,而是操作系统的临时目录,在MySQL Server中不可配置。
所以,你有这种问题,你的文件是一个 csv,你可以将你的“巨大”文件分成块
$ split -l (numbersofrowsinfile / ((filesize/tmpsize) + 1)) /path/to/your/<file>.csv
Run Code Online (Sandbox Code Playgroud)
然后LOAD DATA LOCAL对每个块文件重复您的(步骤 3)。
我将保持这个答案的通用性,因为 Cristian 看起来已经涵盖了大量 MySQL 特定的考虑因素。
对于批量操作的一般建议肯定是随后删除并重建索引。维护每个索引的树结构平衡的工作量相当高,并且根据插入顺序可能会导致显着的索引碎片(即数据文件中页面的位置)和使用的空间量(可能有部分使用的页面比例较高)。
如果表中没有数据,那么一般建议是:
如果表中已有数据,那么这个建议当然需要仔细重新考虑。我记得一条古老的“经验法则”,如果您要添加或更新超过 70% 的表内容,则值得删除并重新创建索引,否则就不需要,但我不知道该规则是否有任何正确的基础进行实验,或者是由一位专家凭空捏造出来并由其他人重复!此外,如果存在现有数据,如果用户主动使用数据库支持的系统,则删除索引和约束将成为问题。
当然,如果时间允许并且您有一台可以在将数据导入生产之前运行测试的机器,您可以在整个过程中运行自己的基准测试。
| 归档时间: |
|
| 查看次数: |
5139 次 |
| 最近记录: |