2014-07-16 9 views
7

Ho creato un database con un'unica collezione che memorizza i documenti con solo 2 campi (e un id):Perché MongoDB non usa l'intersezione dell'indice?

public class Hamster 
{ 
    public ObjectId Id; 
    public string Name; 
    public int Age; 
} 

Ho anche creato un indice per ogni campo.

Quando eseguo un filtro di query su entrambi i campi, mi aspetto che combini entrambi gli indici utilizzando Index Intersection per ridurre la scansione della raccolta e migliorare le prestazioni. Questo è mai il caso. Non sono ancora riuscito a indurre un incrocio di indice.

Quindi, cosa impedisce MongoDB di applicare l'intersezione dell'indice?

risposta

7

Quando si utilizza explain(true) si può vedere che l'ottimizzatore intende far ricorso indice incrocio e sceglie di non:

"cursor" : "BtreeCursor Age", // Chosen plan. 
... 
"allPlans" : [ 
    { 
     "cursor" : "BtreeCursor Age", 
     ... 
    }, 
    { 
     "cursor" : "BtreeCursor Name", 
     ... 
    }, 
    { 
     "cursor" : "Complex Plan", // Index intersection. 
     ... 
    } 
] 

MongoDB potrà mai scegliere intersezione se c'è un indice composto sufficiente. Altre limitazioni possono essere trovati sul Jira ticket for Index Intersection:

Query Optimizer può selezionare i piani di intersezione indice quando le seguenti condizioni:
1. La maggior parte dei documenti della collezione rilevanti sono residente su disco. Il vantaggio dell'intersezione dell'indice è che può evitare di recuperare documenti completi quando la dimensione dell'intersezione è ridotta. Se i documenti sono già in memoria, non c'è nulla da guadagnare evitando i recuperi.
2. I predicati dell'interrogazione sono intervalli a un punto, anziché i predicati di intervallo o un insieme di intervalli. Le query su intervalli a singolo punto restituiscono i documenti ordinati in base alla posizione del disco, che consente all'ottimizzatore di selezionare i piani che calcolano l'intersezione in modo non bloccante. Questo è generalmente più veloce della modalità alternativa di calcolo dell'intersezione, che consiste nel costruire una tabella hash con i risultati di un indice, e quindi analizzarla con i risultati del secondo indice.
3. Nessuno degli indici da intersecare è altamente selettivo. Se uno degli indici è selettivo, l'ottimizzatore sceglierà un piano che scansiona semplicemente questo indice selettivo.
4. La dimensione dell'intersezione è piccola rispetto al numero di chiavi dell'indice scansionate dalla soluzione a indice singolo. In questo caso, la query executor può esaminare un insieme più piccolo di documenti utilizzando l'intersezione dell'indice, che potenzialmente ci consente di sfruttare i vantaggi di un minor numero di recuperi dal disco.

MongoDB ha molte limitazioni sull'intersezione che rendono meno probabile l'effettiva utilizzazione.