Statistiche sulle suddivisioni

Questa pagina descrive come rilevare ed eseguire il debug degli hotspot nel database. Puoi accedere alle statistiche sugli hotspot nelle suddivisioni con GoogleSQL e PostgreSQL.

Spanner archivia i dati come uno spazio delle chiavi contiguo, ordinato in base alle chiavi primarie di tabelle e indici. Una suddivisione è un intervallo di righe di un insieme di tabelle o di un indice. L'inizio della suddivisione è chiamato inizio della suddivisione. Il limite di suddivisione imposta la fine della suddivisione. La suddivisione include l'inizio della suddivisione, ma non il limite della suddivisione.

In Spanner, gli hotspot sono situazioni in cui vengono inviate troppe richieste allo stesso server, il che satura le risorse del server e potenzialmente causa latenze elevate. Le suddivisioni interessate dagli hotspot sono note come suddivisioni frequenti o calde.

La statistica hotspot di una suddivisione (identificata nel sistema come CPU_USAGE_SCORE) è una misurazione del carico su una suddivisione vincolata dalle risorse disponibili sul server. Questa misurazione viene fornita come percentuale. Se più del 50% del carico su una suddivisione è vincolato dalle risorse disponibili, la suddivisione viene considerata calda. Se il 100% del carico su una suddivisione è vincolato, la suddivisione viene considerata calda.

Spanner utilizza la divisione basata sul carico per distribuire uniformemente il carico di dati sui server dell'istanza. Le divisioni calde e molto calde possono essere spostate tra i server per il bilanciamento del carico o possono essere suddivise in divisioni più piccole. Tuttavia, Spanner potrebbe non essere in grado di bilanciare il carico, anche dopo diversi tentativi di suddivisione, a causa di anti-pattern nell'applicazione. Pertanto, gli hotspot persistenti che durano almeno 10 minuti potrebbero richiedere ulteriori risoluzioni dei problemi e potenziali modifiche all'applicazione.

Le statistiche sulla suddivisione frequente di Spanner ti aiutano a identificare le suddivisioni in cui si verificano gli hotspot. Puoi quindi apportare modifiche all'applicazione o allo schema, se necessario. Puoi recuperare queste statistiche dalle tabelle di sistema SPANNER_SYS.SPLIT_STATS_TOP_MINUTE utilizzando le istruzioni SQL.

Accedere alle statistiche della divisione a caldo

Spanner fornisce le statistiche sulla suddivisione frequente nello schema SPANNER_SYS. I dati di SPANNER_SYS sono disponibili solo tramite le interfacce GoogleSQL e PostgreSQL. Puoi utilizzare i seguenti modi per accedere a questi dati:

I seguenti metodi di lettura singola forniti da Spanner non supportano SPANNER_SYS:

  • Esecuzione di una lettura coerente da una o più righe di una tabella.
  • Esecuzione di una lettura obsoleta da una o più righe di una tabella.
  • Lettura da una singola riga o da più righe in un indice secondario.

Statistiche sulle suddivisioni più frequenti

Utilizza la seguente tabella per monitorare le suddivisioni più frequenti:

  • SPANNER_SYS.SPLIT_STATS_TOP_MINUTE: mostra le frazioni più calde durante intervalli di 1 minuto.

Queste tabelle hanno le seguenti proprietà:

  • Ogni tabella contiene dati per intervalli di tempo non sovrapposti della durata specificata dal nome della tabella.
  • Gli intervalli si basano sugli orari:

    • Gli intervalli di 1 minuto terminano al minuto.
  • Dopo ogni intervallo, Spanner raccoglie i dati da tutti i server e li rende disponibili nelle tabelle SPANNER_SYS poco dopo.

    Ad esempio, alle 11:59:30, gli intervalli più recenti disponibili per le query SQL sono:

    • 1 minuto: 11:58:00-11:58:59
  • Spanner raggruppa le statistiche in base alle suddivisioni.

  • Ogni riga contiene una percentuale che indica il livello di frequenza di una suddivisione, per ogni suddivisione per cui Spanner acquisisce statistiche durante l'intervallo specificato.

  • Se meno del 50% del carico su una suddivisione è vincolato dalle risorse disponibili, Spanner non acquisisce la statistica. Se Spanner non è in grado di archiviare tutte le suddivisioni attive durante l'intervallo, il sistema assegna la priorità alle suddivisioni con la percentuale di CPU_USAGE_SCORE più alta durante l'intervallo specificato. Se non vengono restituiti split, significa che non sono presenti hotspot.

Schema tabella

La tabella seguente mostra lo schema della tabella per le seguenti statistiche:

  • SPANNER_SYS.SPLIT_STATS_TOP_MINUTE
Nome colonna Tipo Descrizione
INTERVAL_END TIMESTAMP Fine dell'intervallo di tempo durante il quale la suddivisione era frequente
SPLIT_START STRING La chiave iniziale dell'intervallo di righe nella suddivisione. L'inizio della suddivisione può anche essere <begin>, che indica l'inizio dello spazio delle chiavi
SPLIT_LIMIT STRING La chiave del limite per l'intervallo di righe nella suddivisione. La chiave del limite può anche essere <end>, che indica la fine dello spazio delle chiavi.
CPU_USAGE_SCORE INT64 La percentuale CPU_USAGE_SCORE delle suddivisioni. Una percentuale CPU_USAGE_SCORE del 50% indica la presenza di | suddivisioni | calde o frequenti.
AFFECTED_TABLES STRING ARRAY Le tabelle le cui righe potrebbero essere nella suddivisione.

Chiavi di inizio e limite della suddivisione

Una suddivisione è un intervallo di righe contigue di un database ed è definita dalle chiavi start e limit. Una divisione può essere una singola riga, un intervallo di righe stretto o un intervallo di righe ampio e può includere più tabelle o indici.

Le colonne SPLIT_START e SPLIT_LIMIT identificano le chiavi primarie di una suddivisione calda o frequente.

Schema di esempio

Lo schema seguente è una tabella di esempio per gli argomenti di questa pagina.

GoogleSQL

CREATE TABLE Users (
  UserId INT64 NOT NULL,
  FirstName STRING(MAX),
  LastName STRING(MAX),
) PRIMARY KEY(UserId);

CREATE INDEX UsersByFirstName ON Users(FirstName DESC);

CREATE TABLE Threads (
  UserId INT64 NOT NULL,
  ThreadId INT64 NOT NULL,
  Starred BOOL,
) PRIMARY KEY(UserId, ThreadId),
  INTERLEAVE IN PARENT Users ON DELETE CASCADE;

CREATE TABLE Messages (
  UserId INT64 NOT NULL,
  ThreadId INT64 NOT NULL,
  MessageId INT64 NOT NULL,
  Subject STRING(MAX),
  Body STRING(MAX),
) PRIMARY KEY(UserId, ThreadId, MessageId),
  INTERLEAVE IN PARENT Threads ON DELETE CASCADE;

CREATE INDEX MessagesIdx ON Messages(UserId, ThreadId, Subject),
INTERLEAVE IN Threads;

PostgreSQL

CREATE TABLE users
(
   userid    BIGINT NOT NULL PRIMARY KEY,-- INT64 to BIGINT
   firstname VARCHAR(max),-- STRING(MAX) to VARCHAR(MAX)
   lastname  VARCHAR(max)
);

CREATE INDEX usersbyfirstname
  ON users(firstname DESC);

CREATE TABLE threads
  (
    userid   BIGINT NOT NULL,
    threadid BIGINT NOT NULL,
    starred  BOOLEAN, -- BOOL to BOOLEAN
    PRIMARY KEY (userid, threadid),
    CONSTRAINT fk_threads_user FOREIGN KEY (userid) REFERENCES users(userid) ON
    DELETE CASCADE -- Interleave to Foreign Key constraint
  );

CREATE TABLE messages
  (
    userid    BIGINT NOT NULL,
    threadid  BIGINT NOT NULL,
    messageid BIGINT NOT NULL PRIMARY KEY,
    subject   VARCHAR(max),
    body      VARCHAR(max),
    CONSTRAINT fk_messages_thread FOREIGN KEY (userid, threadid) REFERENCES
    threads(userid, threadid) ON DELETE CASCADE
  -- Interleave to Foreign Key constraint
  );

CREATE INDEX messagesidx ON messages(userid, threadid, subject), REFERENCES
threads(userid, threadid);

Immagina che il tuo spazio delle chiavi sia simile a questo:

CHIAVE PRIMARIA
<begin>
Users()
Threads()
Users(2)
Users(3)
Threads(3)
Threads(3,"a")
Messages(3,"a",1)
Messages(3,"a",2)
Threads(3, "aa")
Users(9)
Users(10)
Threads(10)
UsersByFirstName("abc")
UsersByFirstName("abcd")
<end>

Esempio di suddivisione

Di seguito sono riportati alcuni esempi di suddivisioni per aiutarti a capire come appaiono.

SPLIT_START e SPLIT_LIMIT potrebbero indicare la riga di una tabella o di un indice oppure possono essere <begin> e <end>, che rappresentano i limiti dello spazio delle chiavi del database. SPLIT_START e SPLIT_LIMIT potrebbero contenere anche chiavi troncate, ovvero chiavi che precedono qualsiasi chiave completa nella tabella. Ad esempio, Threads(10) è un prefisso per qualsiasi riga Threads intercalata in Users(10).

SPLIT_START SPLIT_LIMIT AFFECTED_TABLES SPIEGAZIONE
Users(3) Users(10) UsersByFirstName, Users, Threads, Messages, MessagesIdx La suddivisione inizia dalla riga con UserId=3 e termina alla riga precedente a quella con UserId = 10. La suddivisione contiene le righe della tabella Users e tutte le righe delle tabelle interleaved da UserId=3 a 10.
Messages(3,"a",1) Threads(3,"aa") Threads, Messages, MessagesIdx La suddivisione inizia dalla riga con UserId=3, ThreadId="a" e MessageId=1 e termina alla riga precedente a quella con la chiave UserId=3 e ThreadsId = "aa". La suddivisione contiene tutte le tabelle tra Messages(3,"a",1) e Threads(3,"aa"). Poiché split_start e split_limit sono intercalati nella stessa riga della tabella di primo livello, la suddivisione contiene le righe delle tabelle intercalate tra l'inizio e il limite. Consulta schemas-overview per capire come vengono collocate le tabelle con interfoliazione.
Messages(3,"a",1) <end> UsersByFirstName, Users, Threads, Messages, MessagesIdx La suddivisione inizia nella tabella dei messaggi dalla riga con chiave UserId=3, ThreadId="a" e MessageId=1. La suddivisione contiene tutte le righe da split_start a <end>, la fine dello spazio delle chiavi del database. Tutte le righe delle tabelle che seguono split_start, come Users(4), sono incluse nella suddivisione.
<begin> Users(9) UsersByFirstName, Users, Threads, Messages, MessagesIdx La suddivisione inizia da <begin>, l'inizio dello spazio delle chiavi del database, e termina alla riga precedente alla riga Users con UserId=9. Pertanto, la suddivisione contiene tutte le righe della tabella che precedono Users e tutte le righe della tabella Users che precedono UserId=9 e le righe delle relative tabelle con interfoliazione.
Messages(3,"a",1) Threads(10) UsersByFirstName, Users, Threads, Messages, MessagesIdx La suddivisione inizia a Messages(3,"a", 1) intercalata in Users(3) e termina alla riga precedente a Threads(10). Threads(10) è una chiave di suddivisione troncata che è un prefisso di qualsiasi chiave della tabella Threads intercalata in Users(10).
Users() <end> UsersByFirstName, Users, Threads, Messages, MessagesIdx La suddivisione inizia dalla chiave di suddivisione troncata di Users(), che precede qualsiasi chiave completa della tabella Users. La suddivisione si estende fino alla fine dello spazio delle chiavi possibile nel database. Le tabelle interessate coprono quindi la tabella Users, le relative tabelle e indici interleaved e tutte le tabelle che potrebbero essere visualizzate dopo gli utenti.
Threads(10) UsersByFirstName("abc") UsersByFirstName, Users, Threads, Messages, MessagesIdx La suddivisione inizia alla riga Threads con UserId = 10 e termina all'indice UsersByFirstName con la chiave precedente a "abc".

Esempi di query per trovare le suddivisioni più frequenti

L'esempio seguente mostra un'istruzione SQL che puoi utilizzare per recuperare le statistiche di suddivisione a caldo. Puoi eseguire queste istruzioni SQL utilizzando le librerie client, gcloud o la Google Cloud console.

GoogleSQL

SELECT t.split_start,
       t.split_limit,
       t.cpu_usage_score,
       t.affected_tables,
FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE  t.interval_end =
  (SELECT MAX(interval_end)
  FROM    SPANNER_SYS.SPLIT_STATS_TOP_MINUTE)
ORDER BY  t.cpu_usage_score DESC;

PostgreSQL

SELECT t.split_start,
       t.split_limit,
       t.cpu_usage_score,
       t.affected_tables
FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE  t.interval_end = (
  SELECT MAX(interval_end)
  FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE
)
ORDER BY t.cpu_usage_score DESC;

L'output della query è simile al seguente:

SPLIT_START SPLIT_LIMIT CPU_USAGE_SCORE AFFECTED_TABLES
Users(13) Users(76) 82 Messages,Users,Threads
Users(101) Users(102) 90 Messages,Users,Threads
Threads(10, "a") Threads(10, "aa") 100 Messages,Threads
Messages(631, "abc", 1) Messages(631, "abc", 3) 100 Messages
Threads(12, "zebra") Users(14) 76 Messages,Users,Threads
Users(620) <end> 100 Messages,Users,Threads

Conservazione dei dati per le statistiche sulla suddivisione a caldo

Come minimo, Spanner conserva i dati per ogni tabella per il seguente periodo di tempo:

  • SPANNER_SYS.SPLIT_STATS_TOP_MINUTE: intervalli che coprono le 6 ore precedenti.

Risolvere i problemi relativi agli hotspot utilizzando le statistiche sulle suddivisioni che causano un hotspot

Questa sezione descrive come rilevare e risolvere i problemi relativi agli hotspot.

Seleziona un periodo di tempo da esaminare

Controlla le metriche di latenza per il tuo database Spanner per trovare il periodo di tempo in cui la tua applicazione ha riscontrato un'elevata latenza e un elevato utilizzo della CPU. Ad esempio, potrebbe mostrare che un problema è iniziato intorno alle 22:50 del 18 maggio 2024.

Trovare hotspot persistenti

Poiché Spanner bilancia il carico con la divisione basata sul carico, ti consigliamo di verificare se l'hotspotting è continuato per più di 10 minuti. Puoi farlo eseguendo una query sulla tabella SPANNER_SYS.SPLIT_STATS_TOP_MINUTE, come mostrato nell'esempio seguente:

GoogleSQL

SELECT Count(DISTINCT t.interval_end)
FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE  t.cpu_usage_score >= 50
  AND  t.interval_end >= "interval_end_date_time"
  AND  t.interval_end <= "interval_end_date_time";

Sostituisci interval_end_date_time con la data e l'ora dell'intervallo, utilizzando il formato 2024-05-18T17:40:00Z.

PostgreSQL

SELECT COUNT(DISTINCT t.interval_end)
FROM   SPLIT_STATS_TOP_MINUTE t
WHERE  t.cpu_usage_score >= 50
  AND  t.interval_end >= 'interval_end_date_time'::timestamptz
  AND  t.interval_end <= 'interval_end_date_time'::timestamptz;

Sostituisci interval_end_date_time con la data e l'ora dell'intervallo, utilizzando il formato 2024-05-18T17:40:00Z.

Se il risultato della query precedente è uguale a 10, significa che il tuo database sta riscontrando un hotspotting che potrebbe richiedere un ulteriore debug.

Trova le divisioni con il livello di CPU_USAGE_SCORE più alto

Per questo esempio, eseguiamo il seguente SQL per trovare gli intervalli di righe con il livello CPU_USAGE_SCORE più alto:

GoogleSQL

SELECT t.split_start,
       t.split_limit,
       t.affected_tables,
       t.cpu_usage_score
FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE  t.cpu_usage_score >= 50
  AND  t.interval_end = "interval_end_date_time";

Sostituisci interval_end_date_time con la data e l'ora dell'intervallo, utilizzando il formato 2024-05-18T17:40:00Z.

PostgreSQL

SELECT t.split_start,
       t.split_limit,
       t.affected_tables,
       t.cpu_usage_score
FROM   SPLIT_STATS_TOP_MINUTE t
WHERE  t.cpu_usage_score = 100
  AND  t.interval_end = 'interval_end_date_time'::timestamptz;

Sostituisci interval_end_date_time con la data e l'ora dell'intervallo, utilizzando il formato 2024-05-18T17:40:00Z.

L'SQL precedente restituisce il seguente output:

SPLIT_START SPLIT_LIMIT CPU_USAGE_SCORE AFFECTED_TABLES
Users(180) <end> 85 Messages,Users,Threads
Users(24) Users(76) 76 Messages,Users,Threads

Da questa tabella dei risultati, possiamo vedere che si sono verificati hotspot in due split. La divisione basata sul carico di Spanner potrebbe provare a risolvere gli hotspot in queste divisioni. Tuttavia, potrebbe non essere in grado di farlo se ci sono pattern problematici nello schema o nel carico di lavoro. Per rilevare se sono presenti divisioni che richiedono il tuo intervento, ti consigliamo di monitorare le divisioni per almeno 10 minuti. Ad esempio, il seguente SQL monitora la prima divisione negli ultimi 10 minuti.

GoogleSQL

SELECT t.interval_end,
       t.split_start,
       t.split_limit,
       t.cpu_usage_score
FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE  t.split_start = "users(180)"
  AND  t.split_limit = "<end>"
  AND  t.interval_end >= "interval_end_date_time"
  AND  t.interval_end <= "interval_end_date_time";

Sostituisci interval_end_date_time con la data e l'ora dell'intervallo, utilizzando il formato 2024-05-18T17:40:00Z.

PostgreSQL

SELECT t.interval_end,
       t.split_start,
       t.split_limit,
       t.cpu_usage_score
FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE  t.split_start = 'users(180)'
  AND  t.split_limit = ''
  AND  t.interval_end >= 'interval_end_date_time'::timestamptz
  AND  t.interval_end <= 'interval_end_date_time'::timestamptz;

Sostituisci interval_end_date_time con la data e l'ora dell'intervallo, utilizzando il formato 2024-05-18T17:40:00Z.

L'SQL precedente restituisce il seguente output:

INTERVAL_END SPLIT_START SPLIT_LIMIT CPU_USAGE_SCORE
2024-05-18T17:46:00Z Users(180) <end> 85
2024-05-18T17:47:00Z Users(180) <end> 85
2024-05-18T17:48:00Z Users(180) <end> 85
2024-05-18T17:49:00Z Users(180) <end> 85
2024-05-18T17:50:00Z Users(180) <end> 85

La divisione sembra essere stata molto combattuta negli ultimi minuti. Potresti osservare la divisione più a lungo per determinare che la divisione basata sul carico di Spanner mitiga l'hotspot. Potrebbero verificarsi casi in cui Spanner non può bilanciare ulteriormente il carico.

Ad esempio, esegui una query sulla tabella SPANNER_SYS.SPLIT_STATS_TOP_MINUTE. Vedi gli scenari di esempio riportati di seguito.

GoogleSQL

SELECT t.interval_end,
      t.split_start,
      t.split_limit,
      t.cpu_usage_score
FROM  SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE t.interval_end >= "interval_end_date_time"
      AND t.interval_end <= "interval_end_date_time";

Sostituisci interval_end_date_time con la data e l'ora dell'intervallo, utilizzando il formato 2024-05-18T17:40:00Z.

PostgreSQL

SELECT t.interval_end,
       t.split_start,
       t.split_limit,
       t._cpu_usage
FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE  t.interval_end >= 'interval_end_date_time'::timestamptz
  AND  t.interval_end <= 'interval_end_date_time'::timestamptz;

Sostituisci interval_end_date_time con la data e l'ora dell'intervallo, utilizzando il formato 2024-05-18T17:40:00Z.

Singola riga calda

Nell'esempio seguente, sembra che Threads(10,"spanner") si trovi in una singola fila divisa che è rimasta calda per più di 10 minuti. Ciò può accadere quando c'è un carico persistente su una riga popolare.

INTERVAL_END SPLIT_START SPLIT_LIMIT CPU_USAGE_SCORE
2024-05-16T20:40:00Z Threads(10,"spanner") Threads(10,"spanner1") 62
2024-05-16T20:41:00Z Threads(10,"spanner") Threads(10,"spanner1") 62
2024-05-16T20:42:00Z Threads(10,"spanner") Threads(10,"spanner1") 62
2024-05-16T20:43:00Z Threads(10,"spanner") Threads(10,"spanner1") 62
2024-05-16T20:44:00Z Threads(10,"spanner") Threads(10,"spanner1") 62
2024-05-16T20:45:00Z Threads(10,"spanner") Threads(10,"spanner1") 62
2024-05-16T20:46:00Z Threads(10,"spanner") Threads(10,"spanner1") 80
2024-05-16T20:47:00Z Threads(10,"spanner") Threads(10,"spanner1") 80
2024-05-16T20:48:00Z Threads(10,"spanner") Threads(10,"spanner1") 80
2024-05-16T20:49:00Z Threads(10,"spanner") Threads(10,"spanner1") 100
2024-05-16T20:50:00Z Threads(10,"spanner") Threads(10,"spanner1") 100

Spanner non può bilanciare il carico per questa singola chiave perché non può essere ulteriormente suddivisa.

Hotspot mobile

Nell'esempio seguente, il carico si sposta attraverso suddivisioni contigue nel tempo, passando a una nuova suddivisione negli intervalli di tempo.

INTERVAL_END SPLIT_START SPLIT_LIMIT CPU_USAGE_SCORE
2024-05-16T20:40:00Z Threads(1,"a") Threads(1,"aa") 100
2024-05-16T20:41:00Z Threads(1,"aa") Threads(1,"ab") 100
2024-05-16T20:42:00Z Threads(1,"ab") Threads(1,"c") 100
2024-05-16T20:43:00Z Threads(1,"c") Threads(1,"ca") 100

Ciò potrebbe verificarsi, ad esempio, a causa di un carico di lavoro che legge o scrive chiavi in ordine crescente monotono. Spanner non può bilanciare il carico per mitigare gli effetti di questo comportamento dell'applicazione.

Bilanciamento del carico normale

Spanner tenta di bilanciare il carico aggiungendo altre suddivisioni o spostando le suddivisioni. L'esempio seguente mostra come potrebbe apparire.

INTERVAL_END SPLIT_START SPLIT_LIMIT CPU_USAGE_SCORE
2024-05-16T20:40:00Z Threads(1000,"zebra") <end> 82
2024-05-16T20:41:00Z Threads(1000,"zebra") <end> 90
2024-05-16T20:42:00Z Threads(1000,"zebra") <end> 100
2024-05-16T20:43:00Z Threads(1000,"zebra") Threads(2000,"spanner") 100
2024-05-16T20:44:00Z Threads(1200,"c") Threads(2000) 92
2024-05-16T20:45:00Z Threads(1500,"c") Threads(1700,"zach") 76
2024-05-16T20:46:00Z Threads(1700) Threads(1700,"c") 76
2024-05-16T20:47:00Z Threads(1700) Threads(1700,"c") 50
2024-05-16T20:48:00Z Threads(1700) Threads(1700,"c") 39

In questo caso, la suddivisione più grande del giorno 2024-05-16T17:40:00Z è stata ulteriormente suddivisa in una suddivisione più piccola e, di conseguenza, la statistica CPU_USAGE_SCORE è diminuita. Spanner potrebbe non creare suddivisioni in singole righe. Le suddivisioni riflettono il workload che causa la statistica CPU_USAGE_SCORE elevata.

Se hai notato una divisione calda persistente per più di 10 minuti, consulta Best practice per mitigare gli hotspot.

Best practice per mitigare gli hotspot

Se il bilanciamento del carico non riduce la latenza, il passaggio successivo consiste nell'identificare la causa degli hotspot. Dopodiché, le opzioni sono ridurre il carico di lavoro di hotspotting o ottimizzare lo schema e la logica dell'applicazione per evitare gli hotspot.

Identificare la causa

  • Utilizza Statistiche su blocchi e transazioni per cercare transazioni con tempi di attesa blocco elevati in cui la chiave iniziale dell'intervallo di righe si trova all'interno della suddivisione calda.

  • Utilizza Query Insights per cercare query che leggono dalla tabella che contiene la suddivisione calda e che di recente hanno aumentato la latenza o un rapporto più elevato tra latenza e CPU.

  • Utilizza Query attive meno recenti per cercare query che leggono dalla tabella che contiene la suddivisione attiva e che hanno una latenza superiore al previsto.

Alcuni casi particolari a cui prestare attenzione:

  • Controlla se la durata (TTL) è stata attivata di recente. Se ci sono molte suddivisioni di dati precedenti, il TTL può aumentare i livelli di CPU_USAGE_SCORE durante le eliminazioni collettive. In questo caso, il problema dovrebbe risolversi automaticamente una volta completate le eliminazioni iniziali.

Ottimizzare il workload

  • Segui le best practice per SQL. Prendi in considerazione letture non aggiornate, scritture che non eseguono prima le letture o l'aggiunta di indici.
  • Segui le best practice per lo schema. Assicurati che lo schema sia progettato per gestire il bilanciamento del carico ed evitare hotspot.

Passaggi successivi