我有一个使用正则表达式锚点的查询,并且在运行索引扫描而不是集合扫描时似乎更慢。
该问题的一些背景知识:
我有一个MSSQL数据库,表中有大约280万行。我们对表运行以下查询,在23秒内返回大约260万条结果:
从表格中选择*,其中“列”如“IL%”
出于好奇,我决定看看mongodb是否可以比我的MSSQL数据库更快地执行此操作,并且在新的测试服务器上我创建了一个mongodb数据库,我用不到300万个对象填充了1个集合(test1)。这是集合中文档的基本结构:
> db.test1.findOne()
{
"_id" : 2,
"Other_REV" : "NULL",
"Holidex_Code" : "W8BP0",
"Segment_Name" : "NULL",
"Source" : "Forecast",
"Date_" : ISODate("2009-11-12T11:14:00Z"),
"Rooms_Sold" : 3,
"FB_REV" : "NULL",
"Rate_Code" : "ILM87",
"Export_Date" : ISODate("2010-12-12T11:14:00Z"),
"Rooms_Rev" : 51
}
我的所有记录的Rate_Code都以IL为前缀,我对数据库运行了以下查询,花了3秒多时间:
> db.test1.find({'Rate_Code':{$regex: /^IL/}}).explain()
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 2999999,
"nscannedObjects" : 2999999,
"nscanned" : 2999999,
"nscannedObjectsAllPlans" : 2999999,
"nscannedAllPlans" : 2999999,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 4,
"nChunkSkips" : 0,
"millis" : 3398,
"indexBounds" : {
},
"server" : "MONGODB:27017"
}
出于好奇,我创建了一个索引,看看我是否可以加快检索速度:
> db.test1.ensureIndex({'Rate_Code':1})
然而,实际上这似乎会使查询的分辨率平均降低大约6秒:
> db.test1.find({'Rate_Code':{$regex: /^IL/}}).explain()
{
"cursor" : "BtreeCursor Rate_Code_1",
"isMultiKey" : false,
"n" : 2999999,
"nscannedObjects" : 2999999,
"nscanned" : 2999999,
"nscannedObjectsAllPlans" : 2999999,
"nscannedAllPlans" : 2999999,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 4,
"nChunkSkips" : 0,
"millis" : 5895,
"indexBounds" : {
"Rate_Code" : [
[
"IL",
"IM"
]
]
},
"server" : "MONGODB:27017"
}
操作系统有2GB的内存,似乎在内存中非常舒适地保存两个索引,并且在运行查询时没有记录磁盘使用情况:
> db.test1.stats()
{
"ns" : "purify.test1",
"count" : 2999999,
"size" : 623999808,
"avgObjSize" : 208.0000053333351,
"storageSize" : 790593536,
"numExtents" : 18,
"nindexes" : 2,
"lastExtentSize" : 207732736,
"paddingFactor" : 1,
"systemFlags" : 0,
"userFlags" : 0,
"totalIndexSize" : 153218240,
"indexSizes" : {
"_id_" : 83722240,
"Rate_Code_1" : 69496000
},
"ok" : 1
}
我认为减速是由于mongodb执行索引的完整扫描,然后进行完整的收集扫描,因为它不能确定我的所有匹配都在索引中但是我不完全确定情况就是这样。是否有任何方法可以改善这一点以获得更好的性能?
感谢您的帮助。