为什么mongoDB占用了这么多RAM空间?
我已经使用pymongo为mongoDB编写了一个简单的索引器脚本。但我不知道为什么索引、添加文档和查询会占用我服务器上96GB的RAM 是因为我的查询没有优化吗?如何优化查询而不是数据库。find_one{eng:src} 我还可以如何优化索引器脚本 因此,我的输入是这样的:实际数据输入有200多万行不同长度的句子: srcfile trgfile 示例文档如下所示为什么mongoDB占用了这么多RAM空间?,mongodb,indexing,query-optimization,out-of-memory,pymongo,Mongodb,Indexing,Query Optimization,Out Of Memory,Pymongo,我已经使用pymongo为mongoDB编写了一个简单的索引器脚本。但我不知道为什么索引、添加文档和查询会占用我服务器上96GB的RAM 是因为我的查询没有优化吗?如何优化查询而不是数据库。find_one{eng:src} 我还可以如何优化索引器脚本 因此,我的输入是这样的:实际数据输入有200多万行不同长度的句子: srcfile trgfile 示例文档如下所示 { "_id" : ObjectId("50f5fe8916174763f6217994"), "deu"
{
"_id" : ObjectId("50f5fe8916174763f6217994"),
"deu" : "Wie Sie sicher aus der Presse und dem Fernsehen wissen, gab es in Sri
Lanka mehrere Bombenexplosionen mit zahlreichen Toten.\n",
"uid" : 13,
"eng" : "You will be aware from the press and television that there have been a
number of bomb explosions and killings in Sri Lanka."
}
我的代码:
-*-编码:utf8-*-
导入编解码器、全局、操作系统
从pymongo导入MongoClient
从itertools导入izip
从bson.code导入代码
导入系统
重新加载系统
sys.setdefaultencodingutf-8
获取给定值和字典的匹配键的第一个实例。
def getKeydic,值:
返回[k表示k,如果v==值,则在dic.items中返回v]
def langiso lang,isochar=3:
语言{en:eng,
达:丹,德:德,
es:水疗中心,
fi:fin,fr:fre,
it:ita,
nl:nld,
zh:mcn}
如果lenlang==2或isochar==3:
返回语言[lang]
如果lenlang==3或isochar==2:
返回getKeylang
def txtPairs bitextDir:
txtparies={}
对于glob.globos.path.joinbitextDir中的填充,“*”:
印刷填充
k=填充物[-8:-3];lang=infle[-2:]
尝试:
txtpairs[k]=txtpairs[k],如果lang==en-else-infle,则填充,txtpairs[k]
除:
txtpairs[k]=infle
对于txtpairs中的i:
如果lentxtparies[i]!=2:
del txtparies[i]
返回TXT对
def indexEuroparlsfile、tfile、数据库:
trglang=langisotfile[-2:];srclang=langisosfile[-2:]
maxdoc=database.find.sortuid,-1.limit1
如果maxdoc.count==0,则uid=1,否则maxdoc[0]
计数器=0
对于src,在izipcodecs.opensfile、r、utf8中尝试\
编解码器。opentfile,r,utf8:
quid=database.find_one{eng:src}
如果db中已存在句子
如果是英镑!=无:
如果database.find{trglang:{$exists:True}}:
打印句子uniqID,quid[uid]已存在。
持续
其他:
打印重新索引uniqID,quid[uid],。。。
更新{uid:quid[uid]},{$push:{trglang:trg}
其他:
打印索引uniqID、uid、,。。。
doc={uid:uid,eng:src,trglang:trg}
database.insertdoc
uid+=1
如果计数器==1000:
对于数据库中的i.find:
打印i
计数器=0
计数器+=1
连接=MongoClient
db=连接[europarl]
v7=db[v7]
srcfile=eng-deu.en;trgfile=eng-deu.de
indexEuroparlsrcfile,trgfile,v7
为英语-德语对编制索引后,我将对其他语言对执行相同的索引
srcfile=eng-spa.en;trgfile=eng-spa.es
indexEuroparlsrcfile,trgfile,v7
经过几轮代码分析,我找到了RAM泄漏到的地方 首先,如果我想经常查询eng字段,我应该通过以下操作为该字段创建索引:
v7.ensure_index([("eng",1),("unique",True)])
这解决了在未编制索引的eng字段中进行串行搜索所需的时间
其次,RAM放气问题是由于这种代价高昂的函数调用造成的:
doc = {"uid":uid,"eng":src,trglang:trg}
if counter == 1000:
for i in database.find():
print i
counter = 0
counter+=1
MongoDb所做的是将结果存储到RAM中,正如@Sammaye所注意到的那样。每次我调用database.find时,它都会在RAM中保存我添加到集合中的一整套文档。我就是这样消耗掉96GB的内存的。上述代码段需要更改为:
doc = {"uid":uid,"eng":src,trglang:trg}
if counter == 1000:
print doc
counter+=1
通过删除database.find并为eng字段创建索引,我只使用了25GB,并且在不到1小时的时间内完成了200万个句子的索引。为了避免我们试图理解您的代码,您可以给我们看一个示例文档吗?因此,您正在按需要获取的内容进行查询?翻译?如果我错了,请纠正我的错误,但是要获取您正在查找的查询,您必须已经知道您希望提取的查询,这意味着:为什么要执行查询?将getIndexes输出并解释查询最大的问题是字段的大小,我很惊讶MongoDB甚至会对其进行索引,它必须只有1024字节。我不确定是否有任何简单的方法来存储或索引这样一个字段,无论您以何种方式分割该索引,它都将是一个庞大而繁琐的过程query@Sammaye这不是庞大的db应该做的吗?所以我需要询问这些句子之前是否已经被编入索引。循环通过一组新的文本对,我可以为一列添加一行,以进行不同的翻译
doc = {"uid":uid,"eng":src,trglang:trg}
if counter == 1000:
for i in database.find():
print i
counter = 0
counter+=1
doc = {"uid":uid,"eng":src,trglang:trg}
if counter == 1000:
print doc
counter+=1