Domanda

Ho una tabella Azure in cui i clienti pubblicano messaggi, potrebbero esserci milioni di messaggi in una singola tabella. Voglio trovare il modo più veloce per pubblicare i messaggi negli ultimi 10 minuti (che è quanto spesso aggiorno la pagina web). Poiché solo la chiave di partizione è indicizzata, ho giocato con l'idea di usare la data e il tempo il messaggio è stato pubblicato come chiave di partizione, ad esempio una stringa come un formato di data ISO8601 come "2009-06-15t13: 45: 30.0900000"

Esempio di pseudo codice:

var message = "Hello word!";
var messagePartitionKey = DateTime.Now.ToString("o");
var messageEntity = new MessageEntity(messagePartitionKey, message);
dataSource.Insert(messageEntity);

, quindi interrogare per i messaggi pubblicati negli ultimi 10 minuti come questo (di nuovo codice pseudo non testato):

// Get the date and time 10 minutes ago
var tenMinutesAgo = DateTime.Now.Subtract(new TimeSpan(0, 10, 0)).ToString("o");

// Query for the latest messages
var latestMessages = (from t in
   context.Messages
   where t.PartitionKey.CompareTo(tenMinutesAgo) <= 0
   select t
   )

Ma questo sarà preso bene dall'indice? O causerà una scansione a tavola intera? Qualcuno ha un'idea migliore di farlo? So che c'è un timestamp su ogni elemento da tavolo, ma non è indicizzato, quindi sarà troppo lento per il mio scopo.

È stato utile?

Soluzione

Penso che tu abbia l'idea di base giusta. La query che hai progettato dovrebbe essere efficiente come potresti sperare. Ma ci sono alcuni miglioramenti che potrei offrire.

Piuttosto che usare DateTime.Now, uso Date.UtcNow. Da quello che ho capito che le istanze sono impostate per usare il tempo UTC come la loro base comunque, ma questo si assicura solo di confrontare le mele con le mele e puoi convertire il tempo affidabile in qualunque fuso orario desideri durante la visualizzazione.

Piuttosto che conservare il tempo come .ToString("o") Trasforma il tempo in zecche e memorizzalo, finirai con meno problemi di formattazione (a volte otterrai le specifiche del fuso orario alla fine, a volte no). Inoltre, se vuoi sempre vedere questi messaggi ordinati dalla più recente al più antico puoi sottrarre il numero di tick dal numero massimo di tick, ad es.

var messagePartitionKey = (DateTime.MaxValue.Ticks - _contactDate.Ticks).ToString("d19");

Sarebbe anche una buona idea specificare una chiave di riga. Sebbene sia altamente improbabile che due messaggi vengano pubblicati esattamente nello stesso momento, non è impossibile. Se non hai una chiave di riga ovvia, impostalo su GUID.

Altri suggerimenti

La chiave primaria per la tabella è la combinazione di PartitionKey e RowKey (che forma un indice cluster).

Nel tuo caso, scegli RowKey invece di ParitionKey (fornisci un valore costante per questo).

Puoi anche seguire l'approccio diagnostico, come per ogni dieci minuti creare una nuova chiave di partizione. Ma questo approccio è principalmente per requisiti come l'archivio/spurgo ecc.

Suggerirei di fare qualcosa di simile a quello che API diagnostica sta facendo con WadperformanceCounterStable. Lì PartitionKey raggruppa un numero di timestamp in un singolo elemento. IE: arrotola tutti i timestamp in pochi minuti più vicini (diciamo, più vicini 5 minuti). In questo modo non hai una quantità limitata di chiavi di partizione e tuttavia sei ancora in grado di fare domande a distanza.

Quindi, ad esempio, puoi avere una partizione che mappa su ogni timestamp che è arrotondato in 00:00, 00:05, 00:10, 00:15, ecc. E poi convertita in zecche

  • Dalla mia comprensione usando la chiave di partizione con uguale "=" esatto sarà molto più veloce di meno che usare "<" o "maggiore di">.
  • Assicurati anche di fare ulteriori sforzi se possiamo ottenere la combinazione unica della chiave di partizione e della chiave di riga per la tua condizione.
  • Assicurati anche di fare combinazioni meno uniche dei valori delle chiavi della partizione per evitare più partizioni.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top