go backarticles

Articles of SQLschool.gr Team

Cosmos DB Indexes

Antonios Chatzipavlis

Όπως σε όλες τις relational databases έτσι και στην Cosmos DB οι indexes έχουν κυρίαρχη θέση καθώς είναι η κηροζίνη των ερωτημάτων και πρέπει να γνωρίζουμε για αυτούς.

Automatic Indexing

Όλα τα documents σε ένα collection στην Cosmos DB αυτόματα γίνονται indexed με βάση το επιλεγμένο partition key και το Id, και αυτό αποτελεί τον primary index.

Εκτός όμως από αυτόν αυτόματα δημιουργούνται και secondary indexes για κάθε property του document και είναι κάτι που δουλεύει αρκετά καλά σε πολλές περιπτώσεις αλλά όπως πάντα υπάρχει και η άλλη πλευρά στο νόμισμα.

Indexing Policy

Στην Cosmos DB υπάρχει αυτό που ονομάζεται indexing policy και μπορείτε να το βρείτε στο azure portal στο Cosmos DB account > Database > Collection > Scale & Settings.


Image 1 - Indexing Policy from Azure Portal
image1

Το indexing policy είναι ένα json document που περιέχει όλα όσα επηρεάζουν την δημιουργία των indexes στην Cosmos DB και είναι το παρακάτω


Image 2 - Indexing Policy Json from Azure Portal
image2

Για να δούμε κάθε ένα από αυτά τα properties που ορίζουν το indexing policy

Indexing Mode

Με αυτό ορίζεται πότε οι Indexes θα γίνονται update και έχουμε τρεις διαφορετικές επιλογές

  • Consistent: Οι indexes γίνονται update σύγχρονα κάθε φορά που έχω ένα write operation (create, replace, delete). Είναι το default και όπως και στις relational databases έχω overhead στα write operations το οποίο εξαρτάται από το μέγεθος των δεδομένων, αλλά είναι και το επιθυμητό από όλους.
  • Lazy: οι indexes γίνονται update ασύγχρονα κάθε φορά που έχω write operation και σε στιγμές που το σύστημα έχει διαθέσιμους του κατάλληλους πόρους. Φυσικά με το τρόπο αυτό δεν έχω το όποιο overhead αλλά οι indexes δεν είναι πάντα updated και αυτό σημαίνει ότι στα ερωτήματα μου θα έχω διαφορετικά αποτελέσματα.
  • None: δεν έχω indexes και αυτό σημαίνει ότι μπορώ να κάνω αναζητήσεις μόνο με το Id ή το self-URL. Επίσης αν είχα indexes και επιλέξω αυτή την επιλογή διαγράφονται οι υπάρχοντες. Αυτή η επιλογή είναι ουσιαστικά χρήσιμη μόνο όταν έχω key-value storage.

Automatic property

Με αυτό ορίζεται αν θα δημιουργούνται αυτόματα οι indexes και το default είναι true. Αν το κάνουμε false θα πρέπει μόνοι μας να ορίζουμε σε κάθε document την στιγμή που το καταχωρούμε τους index που θέλουμε να έχει.

Included Paths

Tα json documents στην Cosmos DB διαχειρίζονται σαν tree hierarchy και έτσι κάθε property σε αυτά είναι και ένα path στην ιεραρχία.

To path ξεκινάει από το root (“/”) και αυτό ορίζεται στο path property.

Κάθε path τελειώνει με κάποιο από τα παρακάτω patterns:

  • * : δηλώνει τα πάντα μετά από το συγκεκριμένο path/property
  • ? : δηλώνει ότι υπάρχουν πολλαπλές τιμές για το συγκεκριμένο path/property
  • [] : δηλώνει όλα τα elements στο array
Example
{
        "firstName": "Kitsos",
        "lastName": "Leventis",
        "children":[
                {
                        "name": "Pentagiotisa",
                        "age": "20",
                        "school":{
                                "grade": "15",
                                "classes":[
                                        {
                                          "name": "Argaleios"
                                        },
                                        {
                                           "name": "Pleximo"
},
                                        {
                                           "name": "Mageiriki"
                                        }
                                ]
                        }
                },
                {
                        "name": "Astero",
                        "age": "20",
                        "school":{
                                "grade": "12",
                                "classes":[
                                        {
                                           "name": "Argaleios"
                                        },
                                        {
                                           "name": "Anagnosi"
                                        },
                                        {
                                           "name": "Pleximo"
                                        }
                                ]
                        }
                }
        ]
}

Αν θέλω να έχω index για

  • lastName το path είναι /lastName
  • την ηλικία των παιδιών το path είναι /children/age/?
  • τα μαθήματα των παιδιών το path είναι /children/school/*
  • το πρώτο μάθημα των παιδιών το path είναι /children/school/classes[0]/name/?

Μπορώ να έχω όσα includedPaths θέλω (σε array) αλλά κάθε ειδικό κάνει overwrite το γενικό δηλαδή το /children/age/? Κάνει overwrite το /*

Other Index Properties

Για κάθε path υπάρχουν και άλλα properties που μπορώ να ορίζω στο indexing policy όπως

  • dataType: το data type του index και οι τιμές που μπορώ να βάλω είναι String, Number, Point, Polygon, LineString.
  • kind: ο τύπος του index και μπορεί να είναι:
    • Hash: το hash της κάθε τιμής μπαίνει στον index και αυτού του τύπου index είναι κατάλληλοι για συγκρίσεις ισότητας και joins
    • Range: εύρη των τιμών μπαίνουν σε αυτούς και είναι χρήσιμοι σε ερωτήματα με ισότητες, με από – έως και όταν έχω order by
    • Spatial: χρήσιμοι για γεωγραφικά στίγματα και εφαρμόζονται στα point, polygon, linestring data types.
  • Precision: ορίζει το μέγεθος που index δηλαδή το πόσα δεδομένα θα έχει. Για τους hash indexes η τιμή είναι 1-8 με default to 3, για τους range indexes το default είναι -1 και σημαίνει high precision αλλά μπορεί να είναι 1-100 με το 100 να είναι το high precision. Για να υποστηριχθεί το order by θέλουμε high precision index.

Excluded Paths

Με αυτό το property ορίζουμε τα path που δεν θέλουμε να γίνουν indexed και είναι και αυτό ένα json array. Tα paths ορίζονται όπως ακριβώς και στα included paths.

Considerations

Υπάρχουν κάποια πράγματα που πρέπει να γνωρίζουμε γύρω από τους indexes στην Cosmos DB όπως:

Παίρνουμε μήνυμα λάθους και δεν γίνεται η εκτέλεση αν έχουμε range query / operation ή query με order by ή spatial data και δεν έχουμε το αντίστοιχο index.

Αν έχουμε order by query και δεν έχουμε τον αντίστοιχο range index ή δεν έχουμε high precision και θέλουμε να εκτελέσουμε αυτό μπορούμε στο REST API header να κάνουμε true to EnableScanInQuery option

FeedOptions options = new FeedOptions();
options.EnableScanInQuery = true;
var query = this.client.CreateDocumentQuery<ThermometerReading>(temperatureCollection, querySpec, options);

//antonch


Relative Articles

Leave your comment

Login with your SQLschool.gr account if you want to comment on this article.


PASS chapter logo

The Official PASS Local Group for Greece

1434 33 595 27 39 1319
sql school greece logo
© 2010-2019 All rights reserved