
Ya hemos presentado un artículo anterior sobre los tipos de índices disponibles en MongoDB. MongoDB 4.4 se lanzó hace unos meses e introdujo una nueva característica interesante: el índice oculto.
Esta función también está disponible en Percona Server para MongoDB 4.4. En este artículo veremos de qué se trata.
¿Qué es un índice oculto?
Un índice oculto es simplemente un índice regular que no es visible para el programador de consultas. Al evaluar los planes de ejecución, MongoDB ignora este tipo de índice.
Crear un índice en MongoDB es bastante caro, especialmente para colecciones grandes o cuando no tienes suficiente memoria disponible. Deshabilitar el índice es útil para probar diferentes planes de ejecución sin dejar ningún índice real. Puede ocultar o mostrar un índice en cualquier momento sin costo para la base de datos.
Cómo funciona
Usamos una colección de ejemplos de «restaurantes» con documentos como los siguientes:
> db.restaurants.find (). skip (100) .limit (1) .pretty () {«_id»: ObjectId («5f9fec91271d598d55737eb1»), «address»: {«building»: «842», «coord» : [
-73.97063700000001,
40.751495
], «street»: «2 Avenue», «zipcode»: «10017»}, «borough»: «Manhattan», «cuisine»: «Americano», «grados»: [
{
«date» : ISODate(«2014-07-22T00:00:00Z»),
«grade» : «A»,
«score» : 6
},
{
«date» : ISODate(«2013-05-28T00:00:00Z»),
«grade» : «A»,
«score» : 2
},
{
«date» : ISODate(«2012-05-29T00:00:00Z»),
«grade» : «A»,
«score» : 8
},
{
«date» : ISODate(«2012-01-05T00:00:00Z»),
«grade» : «A»,
«score» : 9
},
{
«date» : ISODate(«2011-08-10T00:00:00Z»),
«grade» : «B»,
«score» : 24
}
], «name»: «Restaurante Keats», «restaurant_id»: «40365288»}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
> db.restaurantes.proponer().saltà(100).limite(1).bonito() { «_identificación» : ObjectId(«5f9fec91271d598d55737eb1»), «habla a» : { «construcción» : «842», «coord» : [ –73.97063700000001, 40.751495 ], «camino» : «2 Avenue», «Código postal» : «10017» }, «ciudad» : «Manhattan», «cocina» : «Americano», «grados» : [ { «date» : ISODate(«2014-07-22T00:00:00Z»), «grade» : «A», «score» : 6 }, { «date» : ISODate(«2013-05-28T00:00:00Z»), «grade» : «A», «score» : 2 }, { «date» : ISODate(«2012-05-29T00:00:00Z»), «grade» : «A», «score» : 8 }, { «date» : ISODate(«2012-01-05T00:00:00Z»), «grade» : «A», «score» : 9 }, { «date» : ISODate(«2011-08-10T00:00:00Z»), «grade» : «B», «score» : 24 } ], «primer nombre» : «Restaurante Keats», «restaurant_id» : «40365288» } |
el único índice disponible es _identificación:
> db.restaurants.getIndexes ()
[ { «v» : 2, «key» : { «_id» : 1 }, «name» : «_id_» }
> db.restaurants.getIndexes() [ { «v» : 2, «key» : { «_id» : 1 }, «name» : «_id_» } |
> db.restaurants.createIndex ({municipio: 1}) {«createdCollectionAutomatically»: false, «numIndexesBefore»: 1, «numIndexesAfter»: 2, «ok»: 1}> db.restaurants.createIndex ({cuisine: 1, municipio: 1}) {«createdCollectionAutomatically»: false, «numIndexesBefore»: 2, «numIndexesAfter»: 3, «ok»: 1}
> db.restaurantes.createIndex( { borgo: 1 } ) { «CreatedCollectionAutomatically» : falso, «numberIndexesBefore» : 1, «numIndexesAfter» : 2, «OK» : 1 } > db.restaurantes.createIndex( { cocina: 1 , borgo: 1 } ) { «CreatedCollectionAutomatically» : falso, «numberIndexesBefore» : 2, «numIndexesAfter» : 3, «OK» : 1 } |
Realice una búsqueda simple para encontrar todos los restaurantes italianos en Manhattan y vea el plan ganador.
> db.restaurants.find ({cuisine: «Italian», borough: «Manhattan»}) .explain () {… … «winningPlan»: {«stage»: «FETCH», «inputStage»: { «stage»: «IXSCAN», «keyPattern»: {«cuisine»: 1, «borough»: 1}, «indexName»: «cuisine_1_borough_1», «isMultiKey»: false, «multiKeyPaths»: {«cucina»: [ ], «municipio»: [ ]
}, «isUnique»: false, «isSparse»: false, «isPartial»: false, «indexVersion»: 2, «direction»: «forward», «indexBounds»: {«cuisine»: [
«[«Italian», «Italian»]»],» municipio «: [
«[«Manhattan», «Manhattan»]»]}}}, …
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
> db.restaurantes.proponer( { cocina:«Italiano», borgo:«Manhattan»} ).explique() { ... ... «plan ganador» : { «escena» : «HA PODIDO RECUPERAR», «InputStage» : { «escena» : «IXSCAN», «keyPattern» : { «cocina» : 1, «ciudad» : 1 }, «indexName» : «cucina_1_borough_1», «isMultiKey» : falso, «multiKeyPaths» : { «cocina» : [ ], «ciudad» : [ ] }, «es único» : falso, «está esparcido» : falso, «es parcial» : falso, «indexVersion» : 2, «dirección» : «avanzar», «indexBounds» : { «cocina» : [ «[«Italian», «Italian»]» ], «ciudad» : [ «[«Manhattan», «Manhattan»]» ] } } }, ... |
U {cocina: 1, municipio: 1} se utiliza. Lo ocultamos y volvemos a ejecutar la solicitud.
Para ocultar un dedo índice, simplemente corre hideIndex () método.
> db.restaurants.hideIndex ({cuisine: 1, borough: 1}) {«ok»: 0, «errmsg»: «no se permite que los restaurantes ejecuten el comando {collMod: » restaurants «, índice: {keyPattern: { cocina: 1.0, municipio: 1.0}, oculto: verdadero}, lsid: {id: UUID ( «25d9c931-3dff-49bb-8889-fff3c85c5506 «)}, $ db: «restaurant «} «,» código «: 13,» codeName «:» No autorizado «}
> db.restaurantes.hideIndex( { cocina: 1, borgo: 1 } ) { «OK» : 0, «errmsg» : «restaurantes no autorizados a ejecutar el comando {collMod: » restaurants «, índice: {keyPattern: {cuisine: 1.0, municipio: 1.0}, hidden: true}, lsid: {id: UUID (» 25d9c931- 3dff- 49bb -8889-fff3c85c5506 «)}, $ db: » restaurantes «}», «contraseña» : 13, «nombre clave» : «Dónde autorizar» } |
Ops, si recibe este error, significa que debe solucionarlo setFeatureCompatibility Versión: «4.4». Este es un requisito para ocultar el índice. Entonces, recuerde configurar el parámetro.
> use admin cambiado a db admin> db.adminCommand ({setFeatureCompatibilityVersion: «4.4»}) {«ok»: 1}> use admin cambiado a db restaurants> db.restaurants.hideIndex ({cuisine: 1, borough: 1} ) {«hidden_old»: falso, «hidden_new»: verdadero, «ok»: 1}
> usar administrador cambió a db administrador > db.adminCommand( { setFeatureCompatibilityVersion: «4,4» } ) { «OK» : 1 } > usar restaurantes cambió a db restaurantes > db.restaurantes.hideIndex( { cocina: 1, borgo: 1 } ) { «hidden_old» : falso, «hidden_new» : cierto, «OK» : 1 } |
Veamos el índice de la colección:
> db.restaurants.getIndexes ()
[
{
«v» : 2,
«key» : {
«_id» : 1
},
«name» : «_id_»
},
{
«v» : 2,
«key» : {
«borough» : 1
},
«name» : «borough_1»
},
{
«v» : 2,
«key» : {
«cuisine» : 1,
«borough» : 1
},
«name» : «cuisine_1_borough_1»,
«hidden» : true
}
]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 19 20 21 22 23 24 25 26 |
> db.restaurantes.getIndexes() [ { «v» : 2, «key» : { «_id» : 1 }, «name» : «_id_» }, { «v» : 2, «key» : { «borough» : 1 }, «name» : «borough_1» }, { «v» : 2, «key» : { «cuisine» : 1, «borough» : 1 }, «name» : «cuisine_1_borough_1», «hidden» : true } ] |
Podemos notar que el índice tiene «oculto»: verdadero. Ahora intente la pregunta de nuevo:
> db.restaurants.find ({cocina: «italiana», municipio: «Manhattan»}) .explain () {… … «plan ganador»: {«etapa»: «FETCH», «filtro»: { «cuisine»: {«$ eq»: «Italianu»}}, «inputStage»: {«stage»: «IXSCAN», «keyPattern»: {«borough»: 1}, «indexName»: «borough_1″, » isMultiKey «: false,» multiKeyPaths «: {» municipio «: [ ]
}, «isUnique»: false, «isSparse»: false, «isPartial»: false, «indexVersion»: 2, «direction»: «forward», «indexBounds»: {«borough»: [
«[«Manhattan», «Manhattan»]»]}}},» Planes rechazados «: []
… …
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
> db.restaurantes.proponer( { cocina:«Italiano», borgo:«Manhattan»} ).explique() { ... ... «plan ganador» : { «escena» : «HA PODIDO RECUPERAR», «filtrar» : { «cocina» : { «$ eq» : «Italiano» } }, «InputStage» : { «escena» : «IXSCAN», «keyPattern» : { «ciudad» : 1 }, «indexName» : «borough_1», «isMultiKey» : falso, «multiKeyPaths» : { «ciudad» : [ ] }, «es único» : falso, «está esparcido» : falso, «es parcial» : falso, «indexVersion» : 2, «dirección» : «avanzar», «indexBounds» : { «ciudad» : [ «[«Manhattan», «Manhattan»]» ] } } }, «planes rechazados» : [] ... ... |
Podemos ver que MongoDB usa el otro índice {municipio: 1}. Lo oculto es realmente invisible. Ni siquiera se considera en los planes rechazados. Para hacerlo visible de nuevo, necesitamos usarlo. unhideIndex () método:
> db.restaurants.unhideIndex ({cuisine: 1, municipio: 1}) {«hidden_old»: true, «hidden_new»: false, «ok»: 1}
> db.restaurantes.unhideIndex( { cocina: 1, borgo: 1 } ) { «hidden_old» : cierto, «hidden_new» : falso, «OK» : 1 } |
Notas sobre índices ocultos
- No puede ocultar el índice _id.
- En el momento de la escritura, MongoDB mantiene los índices ocultos al igual que cualquier índice normal.
- Los índices ocultos están disponibles inmediatamente después de mostrarse.
- Un índice único proporciona una limitación de unicidad incluso cuando está oculto.
- Un índice TLL deja documentos incluso si está oculto.
Conclusiones
El nuevo índice oculto en MongoDB 4.4 es una función útil y realmente fácil de usar. Proporciona la capacidad de realizar pruebas contra la usabilidad del índice y evaluar planes de ejecución alternativos, sin tener que abandonar y volver a crear índices.
Obtenga más información sobre la historia de Oracle, el crecimiento de MongoDB y lo que realmente califica al software como código abierto. Si es un DBA o un ejecutivo que busca adoptar o renovar con MongoDB, ¡esta es una lectura obligada!
Descargar «¿MongoDB es el nuevo Oracle?»