sql >> Databasteknik >  >> NoSQL >> MongoDB

Mongo-frågan tar lång tid. Hur gör det snabbare?

Indexet skulle behöva täcka hela delen av frågan (likhetsdel, sorteringsdel och intervalldel). Detta beror på att i en typisk find() fråga använder MongoDB bara ett index. Till exempel använder den i allmänhet inte ett index för jämställdhetsdelen och ett annat index för sorteringsdelen.

I allmänhet måste sekvensen av fält i indexet följa mönstret equality -> sort -> range .

Detta beskrivs i detalj i Optimera MongoDB Compound Indexes .

För din fråga är likhetsdelen tag:..., letterId:... och sorteringsdelen är emailId:-1 . Det finns ingen intervalldel i din fråga.

Med det här mönstret är det sammansatta indexet du behöver:

db.test.createIndex({tag:1, letterId:1, emailId:-1})

Låt oss försöka bekräfta hur mycket prestandaförbättring vi kan få med det här indexet.

Testdata

För att bekräfta indexets lämplighet infogade jag 1 miljon poster i en testdatabas med mgeneratejs , som är ett verktyg för att skapa ett slumpmässigt dokument med hjälp av en mall.

Baserat på ditt exempel, mgeneratejs mall jag använder är:

$ cat template.json
{
  "emailId": "$hash",
  "email": "$email",
  "letterId": "$hash",
  "sendedFrom": "$email",
  "resultMsg": "$word",
  "owner": "$name",
  "created": "$date",
  "result": "$bool",
  "tag": "$word",
  "tryNum": {"$integer": {"min": 0, "max": 1e3}},
  "clickHash": "$word",
  "links": {"$array": {"of": "$url", "number": {"$integer": {"min": 1, "max": 5}}}}
}

och importerade 1 miljon slumpmässiga dokument till MongoDB:

$ mgeneratejs template.json -n 1000000 | mongoimport -d test -c test

Test 1:icke-optimalt index

Sedan skapade jag indexet du har och försökte hitta ett icke-existerande dokument och samlade 10 körningar av frågan med samlingen som bara innehåller detta index:

> db.test.createIndex({emailId: 1, letterId: 1, result: 1, owner: 1, tag: 1, clickHash: 1})

> db.test.find({"tag" : "xyz", "letterId" : "abc"}).sort({emailId: -1}).limit(1)
Fetched 0 record(s) in 3069ms
Fetched 0 record(s) in 2924ms
Fetched 0 record(s) in 2923ms
Fetched 0 record(s) in 3013ms
Fetched 0 record(s) in 2917ms
Fetched 0 record(s) in 2961ms
Fetched 0 record(s) in 2882ms
Fetched 0 record(s) in 2870ms
Fetched 0 record(s) in 2969ms
Fetched 0 record(s) in 2863ms

Så med det indexet är svarstiderna för frågan inte bra, med de flesta exekvering nära 3 sekunder.

Test 2:likhet -> sortering -> intervallindex

Genom att lägga till det optimala likhet -> sortera -> intervallet index:

> db.test.createIndex({tag:1, letterId:1, emailId:-1})

> db.test.find({"tag" : "xyz", "letterId" : "abc"}).sort({emailId: -1}).limit(1)
Fetched 0 record(s) in 2ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 1ms
Fetched 0 record(s) in 3ms

Med det optimala indexet förbättrades däremot prestandan markant. Ingen fråga returnerades på mer än 3 ms, och den stora majoriteten av tiden returneras inom 1 ms.



  1. MongoDB:Skiftlägesokänslig och accentokänslig

  2. Förvandla keymap till vektor med MongoDB ramverk

  3. varför kan jag inte starta mongodb

  4. 4 sätt att ta bort ett dokument i MongoDB