Eseguire una query su un contenitore di Azure Cosmos DB

SI APPLICA A: NoSQL

Questo articolo illustra come eseguire una query su un contenitore (raccolta, grafo o tabella) in Azure Cosmos DB. In particolare, questa guida illustra il funzionamento delle query in partizioni e tra partizioni in Azure Cosmos DB.

Query in partizioni

Quando si esegue una query sui dati dei contenitori, per cui è specificato un filtro della chiave di partizione, Azure Cosmos DB ottimizza automaticamente la query. La query viene instradata alle partizioni fisiche corrispondenti ai valori della chiave di partizione specificati nel filtro.

Si consideri, ad esempio, la query seguente con un filtro di uguaglianza per DeviceId. Se si esegue questa query in un contenitore partizionato su DeviceId, questa query filtra su una singola partizione fisica.

SELECT * FROM c WHERE c.DeviceId = 'XMS-0001'

Come nell'esempio precedente, questa query filtra anche su una singola partizione. L'aggiunta del filtro per Location non modifica la seguente query:

SELECT * FROM c WHERE c.DeviceId = 'XMS-0001' AND c.Location = 'Seattle'

Di seguito è riportata una query che dispone di un filtro di intervallo sulla chiave di partizione e non avrà come ambito una singola partizione fisica. Per essere una query in partizioni, la query deve avere un filtro di uguaglianza che include la chiave di partizione:

SELECT * FROM c WHERE c.DeviceId > 'XMS-0001'

Query tra partizioni

La query seguente non dispone di un filtro sulla chiave di partizione (DeviceId). Pertanto, deve effettuare il fan-out su tutte le partizioni fisiche in cui viene eseguita la query in base all'indice di ogni partizione:

SELECT * FROM c WHERE c.Location = 'Seattle`

Ogni partizione fisica ha il proprio indice. Pertanto, quando si esegue una query tra partizioni su un contenitore, si sta eseguendo effettivamente una query per partizione fisica. Azure Cosmos DB aggrega automaticamente i risultati in partizioni fisiche diverse.

Gli indici in partizioni fisiche diverse sono indipendenti tra loro. Non sono presenti indici globali in Azure Cosmos DB.

Query tra partizioni in parallelo

Le versioni degli SDK di Azure Cosmos DB 1.9.0 e successive supportano le opzioni di esecuzione di query in parallelo. Le query tra partizioni in parallelo consentono di eseguire query tra partizioni a bassa latenza.

È possibile gestire l'esecuzione di query in parallelo, ottimizzando i parametri seguenti:

  • MaxConcurrency: imposta il numero massimo di connessioni di rete simultanee alle partizioni del contenitore. Se si imposta questa proprietà su -1, il grado di parallelismo viene gestito dall'SDK. Se MaxConcurrency è impostato su 0, è presente una singola connessione di rete alle partizioni del contenitore.

  • MaxBufferedItemCount: bilancia la latenza delle query rispetto all'utilizzo della memoria sul lato client. Se questa opzione viene omessa o è impostata su -1, il numero di elementi memorizzati nel buffer durante l'esecuzione di query in parallelo viene gestito dall'SDK.

Grazie alla capacità di Azure Cosmos DB di parallelizzare le query tra partizioni, la latenza delle query viene generalmente ridimensionata man mano che il sistema aggiunge partizioni fisiche. Tuttavia, l'addebito UR aumenta significativamente man mano che aumenta il numero totale di partizioni fisiche.

Quando si esegue una query tra partizioni, si sta essenzialmente eseguendo una query separata per ogni singola partizione fisica. Sebbene le query tra partizioni usino l'indice, se disponibile, esse non sono ancora altrettanto efficienti come le query in partizioni.

Esempio utile

Ecco un'analogia per spiegare meglio le query tra partizioni:

Si supponga di essere un corriere che deve consegnare pacchi a diversi complessi residenziali. Ogni complesso residenziale ha un elenco locale con tutti i numeri delle unità dei residenti. È possibile paragonare ogni complesso residenziale con una partizione fisica e ogni elenco con l'indice della partizione fisica.

L’esempio seguente consente di eseguire il paragone tra query in partizioni e query tra partizioni:

Query in partizioni (esempio)

Se il corriere conosce il complesso residenziale corretto (partizione fisica), può immediatamente dirigersi verso l'edificio corretto. Il corriere può controllare l'elenco dei numeri delle unità del complesso residenziale (indice) dei residenti e consegnare rapidamente i pacchi in maniera corretta. In questo caso, il corriere non perde tempo a dirigersi verso un complesso residenziale per controllare se i destinatari dei pacchi vivono lì.

Query tra partizioni (fan-out)

Se il corriere non conosce il complesso residenziale corretto (partizione fisica), deve dirigersi verso ogni singolo edificio del complesso e controllare l'elenco con tutti i numeri delle unità dei residenti (indice). Una volta arrivato a ogni complesso residenziale, è comunque in grado di usare l'elenco degli indirizzi di ogni residente. Tuttavia, è necessario controllare l'elenco di ogni complesso residenziale, indipendentemente dal fatto che i destinatari dei pacchi vi risiedano o meno. Questo esempio fornisce un’idea del funzionamento delle query tra partizioni. Anche se le query possono utilizzare l'indice (vale a dire che non devono bussare a ogni porta), esse devono controllare separatamente l'indice per ogni partizione fisica.

Query tra partizioni (con ambito limitato a poche partizioni fisiche)

Se il corriere sa che tutti i destinatari dei pacchi vivono all'interno di alcuni complessi residenziali, allora non ha bisogno di dirigersi verso ogni singolo complesso. Anche se dirigersi verso pochi complessi residenziali richiede più lavoro che visitarne uno solo, il corriere risparmia comunque tempo e sforzi significativi. Se una query dispone della chiave di partizione nel filtro con la parola chiave IN, essa controlla solo i dati negli indici della partizione fisica pertinente.

Evitare le query tra partizioni

Per la maggior parte dei contenitori, la presenza di alcune query tra partizioni è inevitabile. Quasi tutte le operazioni di query sono supportate tra partizioni, sia per le chiavi di partizione logiche che per le partizioni fisiche. Azure Cosmos DB include anche molte ottimizzazioni nel motore query e negli SDK client per parallelizzare l'esecuzione di query tra partizioni fisiche.

Per la maggior parte degli scenari con attività di lettura intensiva, è consigliabile selezionare la proprietà più comuni nei filtri di query. È anche necessario assicurarsi che la chiave di partizione sia conforme ad altre procedure consigliate per la selezione della chiave di partizione.

Evitare query tra partizioni in genere è importante solo per i contenitori di grandi dimensioni. Viene addebitato un minimo di circa 2,5 UR ogni volta che si controlla l'indice di una partizione fisica per ottenere risultati anche se nessun elemento nella partizione fisica corrisponde al filtro della query. Di conseguenza, se sono presenti solo una o poche partizioni fisiche, le query tra partizioni non utilizzano un numero significativamente maggiore di UR rispetto alle query in partizioni.

Il numero di partizioni fisiche è associato alla quantità di UR con provisioning. Ogni partizione fisica consente fino a 10.000 UR con provisioning e può archiviare fino a 50 GB di dati. Azure Cosmos DB gestisce automaticamente le partizioni fisiche. Il numero di partizioni fisiche nel contenitore dipende dalla velocità effettiva con provisioning e dall'archiviazione utilizzata.

È consigliabile evitare query tra partizioni se il carico di lavoro soddisfa i seguenti criteri:

  • Si prevede di disporre di oltre 30.000 UR con provisioning
  • Si prevede di archiviare più di 100 GB di dati

Passaggi successivi

Vedere gli articoli seguenti per altre informazioni sul partizionamento in Azure Cosmos DB: