MongoDB大型索引构建非常慢

dav*_*ens 5 indexing performance build mongodb

我有一个包含4亿份文件的藏品.每个都有6个DateTime,1个Boolean,8个Double,9个Integer和6个String字段.我正在尝试构建以下索引:

db.MyCollection.ensureIndex( 
    { "String1" : 1, "String2" : 1, "String3" : 1, "DateTime1" : 1, "Integer1" : 1, "DateTime2" : 1 }, 
    {background: true} 
);
Run Code Online (Sandbox Code Playgroud)

运行5天后,只完成了一半.

该服务器运行的是Windows Server Enterprise,具有4TB磁盘空间和256GB RAM.很少有其他进程针对数据库运行.没有分片或其他特殊配置.

有什么方法可以加快速度吗?(没有删除background = true限定符,因为我不希望它完全关闭我的数据库,在这种情况下它会.)

Mar*_*erg 9

误区

速度

即使不谈多键索引,也会发生这种情况.正在进行大规模的表扫描.所以mongoDB迭代文档,尝试找到要索引的字段,评估该字段(null如果当前文档中不存在),并将其结果写入不少于6个文件,因为我们正在讨论6个索引.做数学:200.000.000/86400*5告诉我们mongoDB 每秒大约460个文档每个文档只需要2.2毫秒.我不会那么慢.这可能需要很长时间,但并不慢.

{background:true}

使用此参数就不是你锁在外面的数据库.恰恰相反,在文档中明确说明了索引创建部分后台创建索引教程部分.但是,有一句话很容易被误解:

此外,在前台索引构建期间,不会对所有数据库(例如listDatabases)执行需要读取或写入锁定的操作.

这意味着您无法执行适用于所有数据库需要读取或写入锁定的操作.

改进的方法(将来)

分片群集

使用具有副本集分片的共享群集.除了提高性能外,它易于设置并具有多种优势.其中之一是易于扩展,添加分片(从而为群集增加空间和计算能力)非常容易.备份对应用程序的影响较小.不再存在单点故障(如果做得对,这甚至适用于整个数据中心规模的中断).

使用不同的文件系统

抱歉,在Windows服务器上运行磁盘依赖性能的应用程序对我来说没有意义 - 完全没有意义.ExtFS4或XFS比NTFS或ReFS快25%到40%,具体取决于优化.这对像您的用例一样依赖磁盘IO的应用程序产生了真正的影响.我们谈论的是几天(甚至没有考虑更高效的内存映射和Linux系统上操作系统的内存消耗减少).

{background:true}

虽然这并没有真正提高性能(实际上,由于显而易见的原因,实际构建索引的时间比前台要长),但您的应用程序在构建索引期间仍然可用.因此,根据您的需求,这可能是一个可行的选择.

附注:使用mongoDB时,垂直缩放是一个坏主意™,因为它明确设计为水平缩放.这尤其适用于像您这样的大型集合,因为并行处理会大大提高应用程序的性能.