我目前正试图说服管理层我们应该将一些数据从MS SQL转移到NOSQL(可能是MongoDB)。具体来说,我想要移动的是我们的WebStats系统。目前我们在一个表中有大约1.5亿行,而且这个数据集总是在增长(我们存储了数年的统计数据。)
作为测试,我运行了以下查询1.5亿次:
db.test.insert({SiteId:1,PageUrl:“/ home /”,印象数:1,日期:新日期(), IsCrawler:false,LanguageId:2057,ClientIpAddress:“1.2.3.4”,DateTime:new Date( ),ReferalUrl:“http://www.google.com”,UniqueUserGuid:1,BrowserName:“IE”,Brow serVersion:11,BrowserAgent:“blah”,IsAbcValid:true,hasChecked:true,connection 速度:1,国家:“英国”,地区:“米德兰兹”,城市:“考文垂”})
然后我执行一次:
db.test.insert({SiteId:1,PageUrl:“/ home /”,印象数:1,日期:新日期(), IsCrawler:false,LanguageId:2057,ClientIpAddress:“1.2.3.4”,DateTime:new Date( ),ReferalUrl:“http://www.google.com”,UniqueUserGuid:1,BrowserName:“IE”,Brow serVersion:11,BrowserAgent:“blah”,IsAbcValid:true,hasChecked:true,connection 速度:1,国家:“美国”,地区:“纽约”,城市:“纽约”})
其次是:
db.test.ensureIndex({“PageUrl”:1,“Date”:1,“ClientIpAddress”:1})
索引编制完成后,我运行了以下搜索:
db.test.find({国家:/ S /})
它最终找到了我添加的美国文档,但它花费的时间比在MS SQL中要长。我错误地索引了这个吗?我基本上只是试图抨击可能的性能提升的演示,所以如果有人能指出我处理非常大的数据集的例子,那么我很乐意使用它。
谢谢,
乔
答案 0 :(得分:3)
您必须按国家/地区编制索引才能进行搜索。如果您不想使用这样的正则表达式,索引通常不会有帮助,除非它位于字符串的前面。
db.test.find({Country:{$regex:"^US"}})
答案 1 :(得分:1)
如果您正在国家/地区运行查询,则应创建类似db.test.ensureIndex({Country:1})
的索引。
答案 2 :(得分:1)
问题中的索引位于错误的字段上,但假设已更正,则查询仍然会很慢。
来自the docs:
$ regex只能在正则表达式具有字符串开头(即^)的锚点时有效地使用索引,并且是区分大小写的匹配。
此查询:
db.test.find({国家:/ S /})
不以固定字符串开头,因此无法有效地使用索引。使用explain,可以研究这种正则表达式查询的影响,例如:
> db.test.find({Country:/S/}).explain();
{
"cursor" : "BtreeCursor Country_1 multi",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 150000000,
"nscannedObjectsAllPlans" : 1,
"nscannedAllPlans" : 2,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"Country" : [
[
"",
{
}
],
[
/S/,
/S/
]
]
},
"server" : "host.local:27017"
}
请注意nscanned
的{{3}}值。索引是,但无论匹配对象的数量如何,都需要扫描整个索引。
更好的想法是确定此字段的哪些值可以匹配,并明确搜索这些值:
> db.test.find({Country:['US']}).explain();
> # ^ derive this list
{
"cursor" : "BtreeCursor Country_1 multi",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 1,
"nscannedAllPlans" : 1,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"Country" : [
[
"US",
"US"
],
[
[
"US"
],
[
"US"
]
]
]
},
"server" : "host.local:27017"
}
请注意,在这种情况下,nscanned
的值与nscannedObjects
相同 - 表示有效使用索引,可能很多更快的查询。