关于mongodb查询子文档优化的问题(LOL对战详情查询)
过去多啦不再A梦
过去多啦不再A梦 2017-05-02 09:18:33
0
1
670

图为mongodb中一条document结构,记录的是LOL的一场比赛对局详情
participants中有10个玩家,前5个teamID为100,后5个teamId为200.比赛的结果哪个队伍取胜是记录在teams那个子文档中的。
我现在的想要查询championId为64(盲僧), 157(亚索)这两个英雄在同一个队伍时的胜利场次,(规定游戏版本号>6.7),查询语句我是这样写的:

db.getCollection('matches').count({ $and: [ { "matchVersion": {$gte:"6.7"} } , { $or: [ { $and: [ { "participants": {$elemMatch: {"teamId": 100, "championId": 64 } } } , { "participants": {$elemMatch: {"teamId": 100, "championId": 157 } } } , { "teams":{ $elemMatch: {"teamId": 100, "winner":true} } } ] }, { $and: [ { "participants": {$elemMatch: {"teamId": 200, "championId": 64 } } } , { "participants": {$elemMatch: {"teamId": 200, "championId": 157 } } } , { "teams":{ $elemMatch: {"teamId": 200, "winner":true} } } ] } ] } ] } )

数据规模为14万,可是执行这样一个查询要花费3秒。已经对对应的查询建立了索引。对查询explain的结果如下

不过好像有些索引也没有用到,比如teams.teamId,teams.winner的复合索引,matchVersion的索引

请问这个查询该如何优化呢?我觉得这个数据规模花费这么久时间应该是我的使用姿势不对吧?

过去多啦不再A梦
过去多啦不再A梦

Antworte allen (1)
淡淡烟草味

你的执行计划索引是用了,但是能看出来效率不高,但是很多关键信息被折叠了,无法看出详细内容。下次最好直接发原始的JSON会更容易看懂。同样如果有数据样例也最好发一个JSON出来,这样别人在解决问题的时候可以有一份测试数据,会方便很多。
$and这个东西大部分时候是不用出现的,一个对象中的两个并列的元素就是与的关系。这样可以简化你的查询结构,别人看起来也轻松些。所以对你的查询做了简化,如下:

db.getCollection('matches').count({ "matchVersion": {$gte: "6.7"}, $or: [{ "participants": {$elemMatch: {"teamId": 100, "championId": 64}}, "participants": {$elemMatch: {"teamId": 100, "championId": 157}}, "teams": {$elemMatch: {"teamId": 100, "winner": true}} }, { "participants": {$elemMatch: {"teamId": 200, "championId": 64}}, "participants": {$elemMatch: {"teamId": 200, "championId": 157}}, "teams": {$elemMatch: {"teamId": 200,"winner": true}} }] })

最后最关键的索引问题,推测对你更有用的索引应该是participants.teamId+participants.championId+teams.teamId+teams.winner+matchVersion的联合索引,应该根据条件的过滤性把过滤性更好的条件放前面。甚至去掉一些条件以提高写入效率。但这取决于你的数据分布情况。
为什么你的索引没有被用到,mongodb 2.6以后虽然支持交叉索引,可以使用多个索引来满足同一个查询,但目前的执行计划评估的体系使得交叉索引很难被触发。所以要尽可能用一个索引来满足你的查询。

    Neueste Downloads
    Mehr>
    Web-Effekte
    Quellcode der Website
    Website-Materialien
    Frontend-Vorlage
    Über uns Haftungsausschluss Sitemap
    Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!