我需要将大型数据集加载到生产数据库中。
需要上传15个文件并插入表格中。 每个约 500 Mb 。
我有两个需要索引的ID列。 如果我加载了包含索引的文件,则上传大约需要3个小时。 如果我删除索引,加载数据本地infile,然后重新添加索引,整个操作大约需要30分钟。
问题是,数据库响应性受到重创,同时索引新导入的数据。有没有办法让索引运行在“低优先级”,以便其他查询仍然可以获得95-100%的速度和背景中的索引类型的突变?
我正在使用 Amazon RDS ,所以我没有选择只在其他服务器上加载然后复制表文件。
为此添加赏金,因为我仍然想知道在特定方框上编制索引时是否有办法获得良好的效果。
答案 0 :(得分:4)
好吧,我从来没有找到过节流的方法,但我确实找到了解决问题的方法。 解决方案对我的问题是独一无二的,但是我会发布它以防其他人发现它有用。
我写了一个名为CautiousIndexer
的类。
prevent_indexing_($name)
。 这在效率方面仍然很好,但在主服务器上的索引编写期间,写入性能下降得令人无法接受。仍在寻找一种以节流为目标的方法。
答案 1 :(得分:1)
这不是您正在寻找的确切解决方案,但您可以在此单个框上提出a second mysqld instance as a slave,并根据需要将SELECT
次问题重定向到它。有MySQL Proxy可以帮助您完成此操作而无需重写客户端应用程序。
您还可以从FriendFeed usage of MySQL收集一些想法。它们将实际索引存储在其他表中并将其用于搜索。如果您将数据的副本存储在其他表中甚至在其他服务器上并在那里运行索引,您将能够全速访问主数据并在以后使用其他服务器获得更快的查询。
就像在奴隶上为搜索类型查询添加索引并在主服务器上仅运行主键查找一样。
答案 2 :(得分:1)
一个很好的解决方案是执行滚动更新的脚本。您可以以非复制方式将索引应用于每个从属服务器。粗略的说明:
for host in $hosts
do
mysql -h $host -e "STOP SLAVE;\
SET sql_log_bin=0;\
FLUSH TABLE t;\
ALTER TABLE t ADD INDEX a (b,c);\
SET sql_log_bin=1;\
START SLAVE;"
done
通过关闭复制,应减少磁盘活动量并提高索引操作的速度。如果您的从服务器有数据库延迟要求,则可能需要完全解除对从服务器的分离,并包含在从服务器恢复零秒滞后时重新集中服务器的逻辑。
答案 3 :(得分:0)
之前没有尝试过的想法也没有关于索引限制,如果你制作一个备份表并用你提到的方式更新它的时间跨度更短,而不是转换/重命名表。我鼓励用b / c写出你需要知道的方法。
答案 4 :(得分:0)
您可以在插入时禁用任何非唯一索引,并在完成后重新启用它们。看看禁用键/启用键。但它仅适用于非唯一索引。
如果使用多值插入语句(插入表(...)值(...),(...),(...)...... >也可以加快插入速度。
顺便说一下,加载数据infile似乎是在mysql中插入大量数据的最快方法。
答案 5 :(得分:0)
您是否尝试过升级导入的索引设置?这可以显着提高进口表现。 sort_buffer_size适用于任何表类型,myisam_sort_buffer_size适用于MyISAM表。 innodb_buffer_pool_size是Innodb的“关键缓存”。根据您的表类型,将这些用于导入。您要做的是在索引创建期间避免文件排序。
您可以将导入/索引时间缩短到10-15分钟或更短。它不会受到限制,但会显着缩短影响期。
或者,如果您使用的是MyISAM表,那么MERGE表可能是一个选项吗?创建一个新表,执行导入,而不是将新表添加到MERGE表。导入期间对数据库没有影响。除了执行任务的服务器。