sql >> Database >  >> NoSQL >> MongoDB

MongoDB samengestelde indexen - Is de sorteervolgorde van belang?

U kunt MongoDB single-field index zien als een array, met verwijzingen naar documentlocaties. Als u bijvoorbeeld een verzameling heeft met (merk op dat de volgorde opzettelijk niet in orde is):

[collection]
1: {a:3, b:2}
2: {a:1, b:2}
3: {a:2, b:1}
4: {a:1, b:1}
5: {a:2, b:2}

Enkelveldindex

Als je dat nu doet:

db.collection.createIndex({a:1})

De index ziet er ongeveer zo uit:

[index a:1]
1: {a:1} --> 2, 4
2: {a:2} --> 3, 5
3: {a:3} --> 1

Let op drie belangrijke dingen:

  • Het is gesorteerd op a oplopend
  • Elke ingang wijst naar de locatie waar de relevante documenten zich bevinden
  • De index registreert alleen de waarden van de a veld. De b veld bestaat helemaal niet in de index

Dus als je een zoekopdracht doet zoals:

db.collection.find().sort({a:1})

Het enige wat het hoeft te doen is de index van boven naar beneden te doorlopen, het document op te halen en uit te voeren waarnaar wordt verwezen door de vermeldingen. Merk op dat u de index ook vanaf de onderkant kunt doorlopen, bijvoorbeeld:

db.collection.find().sort({a:-1})

en het enige verschil is dat je de index achteruit loopt.

Omdat b staat helemaal niet in de index, u kunt de index niet gebruiken als u iets opvraagt ​​over b .

Samengestelde index

In een samengestelde index bijv.:

db.collection.createIndex({a:1, b:1})

Dit betekent dat u wilt sorteren op a eerst, dan sorteren op b . De index zou er als volgt uitzien:

[index a:1, b:1]
1: {a:1, b:1} --> 4
2: {a:1, b:2} --> 2
3: {a:2, b:1} --> 3
4: {a:2, b:2} --> 5
5: {a:3, b:2} --> 1

Merk op dat:

  • De index is gesorteerd op a
  • Binnen elke a je hebt een gesorteerde b
  • Je hebt 5 indexitems versus slechts drie in het vorige voorbeeld met één veld

Met behulp van deze index kunt u een zoekopdracht uitvoeren als:

db.collection.find({a:2}).sort({b:1})

Het kan gemakkelijk vinden waar a:2 loop dan de index naar voren. Gezien die index, kun je niet doen :

db.collection.find().sort({b:1})
db.collection.find({b:1})

In beide zoekopdrachten kun je b niet gemakkelijk vinden omdat het over de hele index is verspreid (d.w.z. niet in aaneengesloten items). Hoe dan ook, u kunt doen:

db.collection.find({a:2}).sort({b:-1})

omdat je in wezen kunt vinden waar de a:2 zijn, en loop de b invoer achteruit.

Bewerken :verduidelijking van de vraag van @marcospgp in de opmerking:

De mogelijkheid om de index {a:1, b:1} . te gebruiken om te voldoen aan find({a:2}).sort({b:-1}) eigenlijk logisch als je het vanuit het oogpunt van een gesorteerde tabel bekijkt. Bijvoorbeeld de index {a:1, b:1} kan worden gezien als:

a | b
--|--
1 | 1
1 | 2
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2

find({a:2}).sort({b:1})

De index {a:1, b:1} betekent sort by a, then within each a, sort the b values . Als je dan een find({a:2}).sort({b:1}) . doet , weet de index waar alle a=2 zijn. Binnen dit blok van a=2 , de b zou in oplopende volgorde worden gesorteerd (volgens de indexspecificatie), zodat zoekopdracht find({a:2}).sort({b:1}) kan worden voldaan door:

a | b
--|--
1 | 1
1 | 2
2 | 1 <-- walk this block forward to satisfy
2 | 2 <-- find({a:2}).sort({b:1})
2 | 3 <--
3 | 1
3 | 2

find({a:2}).sort({b:-1})

Aangezien de index naar voren of naar achteren kan worden gelopen, werd een vergelijkbare procedure gevolgd, met een kleine draai aan het einde:

a | b
--|--
1 | 1
1 | 2
2 | 1  <-- walk this block backward to satisfy
2 | 2  <-- find({a:2}).sort({b:-1})
2 | 3  <--
3 | 1
3 | 2

Het feit dat de index vooruit of achteruit kan worden gelopen, is het belangrijkste punt dat de zoekopdracht find({a:2}).sort({b:-1}) mogelijk maakt. om de index {a:1, b:1} . te kunnen gebruiken .

Query planner uitleg

U kunt zien wat de queryplanner van plan is door db.collection.explain().find(....) te gebruiken . In principe als je een stage . ziet van COLLSCAN , er is geen index gebruikt of kan worden gebruikt voor de query. Zie resultaten uitleggen voor details over de uitvoer van de opdracht.



  1. Een sleutel/waarde verwijderen uit bestaande MongoDB-invoer

  2. Redis-concept:in geheugen of DB?

  3. Aggregatiepijplijnstadia voorwaardelijk opnemen

  4. socket.io redis en geheugenlek