sql >> Base de Datos >  >> NoSQL >> MongoDB

Índice compuesto triple de Mongo

resultado final / tl;dr: Índice b se puede 'omitir' si a y c se consultan por igualdad o desigualdad, pero no, por ejemplo, por ordenaciones en c .

Esta es una muy buena pregunta. Desafortunadamente, no pude encontrar nada que responda con autoridad a esto con mayor detalle. Creo que el rendimiento de este tipo de consultas ha mejorado en los últimos años, por lo que no confiaría en el material antiguo sobre el tema.

Todo es bastante complicado porque depende de la selectividad de sus índices y si consulta por igualdad, desigualdad u ordenación, así que explain() es tu único amigo, pero aquí hay algunas cosas que encontré:

Advertencia :Lo que viene ahora es una mezcla de resultados experimentales, razonamiento y conjeturas. Puede que esté exagerando demasiado la analogía de Kyle y incluso podría estar completamente equivocado (y desafortunado, porque los resultados de mi prueba coinciden vagamente con mi razonamiento).

Está claro que se puede utilizar el índice de A, que, dependiendo de la selectividad de A, es sin duda muy útil. 'Omitir' B puede ser complicado, o no. Mantengamos esto similar al ejemplo del libro de cocina de Kyle:

French
    Beef
        ...
    Chicken
        Coq au Vin
        Roasted Chicken
    Lamb
        ...
    ...

Si ahora me pide que busque un plato francés llamado "Chateaubriand", puedo usar el índice A y, como no conozco el ingrediente, tendré que escanear todos los platos en A . Por otro lado, sí sé que la lista de platos de cada categoría está ordenada a través del índice C , así que solo tendré que buscar las cadenas que comienzan con, por ejemplo, "Cha" en cada lista de ingredientes. Si hay 50 ingredientes, necesitaré 50 búsquedas en lugar de solo una, ¡pero eso es mucho mejor que tener que escanear cada plato francés!

En mis experimentos, el número era mucho más pequeño que el número de valores distintos en b :nunca pareció exceder 2. Sin embargo, probé esto solo con una sola colección, y probablemente tenga que ver con la selectividad de b -índice.

Si me pidieras que te diera una lista ordenada alfabéticamente de todos los platos franceses , sin embargo, estaría en problemas . Ahora el índice en C no tiene valor, tendría que fusionar y clasificar todas esas listas de índice. Tendré que escanear cada elemento para hacerlo.

Esto se refleja en mis pruebas. Aquí hay algunos resultados simplificados. La colección original tiene fechas, horas, enteros y cadenas, pero quería simplificar las cosas, por lo que ahora son todos enteros.

Esencialmente, solo hay dos clases de consultas:aquellas donde nscanned <=2 * limit , y los que tienen que escanear toda la colección (120k documentos). El índice es {a, b, c} :

// fast (range query on c while skipping b)
> db.Test.find({"a" : 43, "c" : { $lte : 45454 }});
// slow (sorting)
> db.Test.find({"a" : 43, "c" : { $lte : 45454 }}).sort({ "c" : -1});
> db.Test.find({"a" : 43, "c" : { $lte : 45454 }}).sort({ "b" : -1}); 

// fast (can sort on c if b included in the query)
> db.Test.find({"a" : 43, "b" : 7887, "c" : { $lte : 45454 }}).sort({ "c" : -1});

// fast (older tutorials claim this is slow)
> db.Test.find({"a" : {$gte : 43}, "c" : { $lte : 45454 }});

Su millaje variará.