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

图为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梦

membalas semua(1)
淡淡烟草味

Indeks pelan pelaksanaan anda digunakan, tetapi dapat dilihat bahawa kecekapannya tidak tinggi, tetapi banyak maklumat penting dilipat, dan kandungan terperinci tidak dapat dilihat. Lain kali adalah lebih baik untuk menghantar JSON asal secara terus kerana ia akan lebih mudah difahami. Begitu juga, jika anda mempunyai sampel data, lebih baik menghantarnya dalam JSON, supaya orang lain boleh mempunyai salinan data ujian semasa menyelesaikan masalah, yang akan menjadi lebih mudah.
$andPerkara ini tidak perlu muncul pada kebanyakan masa Dua elemen selari dalam objek ialah hubungan antara dan. Ini memudahkan struktur pertanyaan anda dan memudahkan orang lain melihat. Jadi pertanyaan anda telah dipermudahkan seperti berikut:

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}}
    }]
})

Isu indeks yang terakhir dan paling kritikal ialah terdapat spekulasi bahawa indeks yang lebih berguna kepada anda haruslah indeks bersama participants.teamId+participants.championId+teams.teamId+teams.winner+matchVersion. Ia harus ditapis mengikut kebolehsaringan keadaan Utamakan keadaan seksual yang lebih baik. Malah alih keluar beberapa syarat untuk meningkatkan kecekapan penulisan. Tetapi ia bergantung pada pengedaran data anda.
Mengapa indeks anda tidak digunakan? Walaupun mongodb 2.6 dan lebih baru menyokong pengindeksan silang dan berbilang indeks boleh digunakan untuk memenuhi pertanyaan yang sama, sistem penilaian pelan pelaksanaan semasa menyukarkan untuk mencetuskan indeks silang. Jadi cuba gunakan indeks untuk memenuhi pertanyaan anda.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan