国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

mongodb - 百萬數(shù)據(jù)aggregate group sum 統(tǒng)計超級耗時的問題,求解決方案
PHPz
PHPz 2017-05-02 09:20:16
0
3
2084

1、文檔結(jié)構(gòu)示例

{
    _id: xxxx,
    user: 'xiaoming',
    level: 5,
    from: 'iPhone',
    info: 'something wrong'
}

2、場景:user為'xiaoming'的文檔有六七百萬條

3、問題:怎么提升aggregate+group+sum速度

aggregate([
    {$match:{user: 'xiaoming', info:{$regex:'wrong'}}},
    {$group:{_id:null, count:{$sum:1}}}
])

用上面這個來統(tǒng)計xiaoming帶有wrong的文檔數(shù)量,結(jié)果

{"_id": null, "count": 2299999 }

耗時30s-40s。user、info、user+info三種索引都嘗試過,速度都沒有提升
baidu、google查到‘帶條件計數(shù)慢無解’
怎么提升效率,10s以內(nèi)能實現(xiàn)嗎

PHPz
PHPz

學習是最好的投資!

Antworte allen(3)
洪濤

首先要說明的一個問題是,對于OLAP型的操作,期望不應該太高。畢竟是對于大量數(shù)據(jù)的操作,光從IO就已經(jīng)遠超通常的OLTP操作,所以要求達到OLTP操作的速度和并發(fā)是不現(xiàn)實的,也是沒有意義的。但并不是說一點優(yōu)化空間也沒有。
我們先從索引入手。在沒有索引的前提下,找出600萬條{user: "xiaoming"}需要多少時間?全表掃描COLLSCAN從700w條數(shù)據(jù)中找出600w條,跟從1億條數(shù)據(jù)中找出600w條顯然是兩個概念。命中索引IXSCAN,這個差異就會小很多,幾乎可以忽略。所以你說{user: 1}這個索引沒有作用是不對的,可能只是因為集合數(shù)據(jù)量太少看不出差異而已。順便應該提一下看效率是否有差異應該看執(zhí)行計劃,不要看執(zhí)行時間,時間是不準確的。
在有user索引的前提下,結(jié)果仍然有600w條,剩下的部分是個regexregex無法命中索引,所以不管有沒有對info的索引都沒有意義。在找到600w條數(shù)據(jù)之后還有一個對600w數(shù)據(jù)的filter操作。唯一對這個操作可能有幫助的只有全文索引,但全文索引并不能完全替代正則,具體問題需要讀一下文檔??紤]全文索引可行的情況下,可以建立復合索引:

db.coll.createIndex({
  user: 1,
  info: "text"
});

對應地查詢應該改為:

db.coll.aggregate([
  {$match:{user: 'xiaoming', $text: { $search: "wrong" }}},
  {$group:{_id:null, count:{$sum:1}}}
])

關(guān)于復合全文索引的介紹參考這里,仍然是有些限制需要注意。這樣優(yōu)化之后預計在同樣的硬件下能降到20s以內(nèi),跟你要的10s內(nèi)還有一段距離。原因開頭說了,對OLAP就不能期望這么高。如果你真有這方面的需求,就應該從源頭入手,考慮:

  1. 每次info字段有更新或插入時就做好計數(shù)
    或者

  2. 每隔一段時間做一次完整的統(tǒng)計,緩存統(tǒng)計結(jié)果,查詢的時候直接展現(xiàn)給用戶

某草草

不了解,不過能不能拆分成兩個match會不會好一點呢。。

類似于

aggregate([
    {$match:{user: 'xiaoming'}},
    {$match:{info: /wrong/}},
    {$group:{_id:null, count:{$sum:1}}}
])

主要我認為正則花時間。
有index的話,index一下user。

給我你的懷抱

實時性要求不高 可以定時統(tǒng)計 + 緩存

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage