Dirò fin dall'inizio che la mia domanda / problema è simile a questo precedente, ma dal momento che non sono sicuro se la causa o le informazioni di partenza è lo stesso, ho deciso di pubblicare la mia domanda con qualche dettaglio in più.
Problema a portata di mano:
- a un'ora strana (verso la fine della giornata lavorativa) un'istanza di produzione inizia a comportarsi in modo irregolare:
- CPU elevata per l'istanza (da una base di circa il 30% è passata a circa il doppio ed era ancora in crescita)
- aumento del numero di transazioni / sec (anche se il caricamento dell'app non ha visto alcun cambiamento)
- aumento del numero di sessioni inattive
- strani eventi di blocco tra sessioni che non hanno mai mostrato questo comportamento (anche leggere sessioni senza commit causavano il blocco)
- le prime attese per l'intervallo erano il blocco della pagina al 1 ° posto, con i blocchi che occupavano il 2 ° posto
Indagine iniziale:
- usando sp_whoIsActive abbiamo visto che una query eseguita dal nostro strumento di monitoraggio decide di funzionare in modo estremamente lento e catturare molta CPU, cosa che prima non accadeva;
- il suo livello di isolamento è stato letto senza commit;
- abbiamo esaminato il piano in cui abbiamo visto numeri stravaganti: StatementEstRows = "3.86846e + 010" con circa 150 TB di dati stimati da restituire
- sospettavamo che la causa fosse una funzionalità di monitoraggio delle query dello strumento di monitoraggio, quindi abbiamo disabilitato la funzione (abbiamo anche aperto un ticket con il nostro provider per verificare se sono a conoscenza di eventuali problemi)
- da quel primo evento, è successo un paio di volte in più, ogni volta che uccidiamo la sessione, tutto torna alla normalità;
- ci rendiamo conto che la query è estremamente simile a una delle query utilizzate da MS in BOL per il monitoraggio del Query Store - Query recentemente regredite nelle prestazioni (confrontando diversi punti nel tempo)
- eseguiamo la stessa query manualmente e vediamo lo stesso comportamento (CPU utilizzata in costante aumento, in attesa di latch, blocchi imprevisti ecc.)
Query colpevole:
Select qt.query_sql_text,
q.query_id,
qt.query_text_id,
rs1.runtime_stats_id AS runtime_stats_id_1,
interval_1 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi1.start_time),
p1.plan_id AS plan_1,
rs1.avg_duration AS avg_duration_1,
rs2.avg_duration AS avg_duration_2,
p2.plan_id AS plan_2,
interval_2 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi2.start_time),
rs2.runtime_stats_id AS runtime_stats_id_2
From sys.query_store_query_text AS qt
Inner Join sys.query_store_query AS q
ON qt.query_text_id = q.query_text_id
Inner Join sys.query_store_plan AS p1
ON q.query_id = p1.query_id
Inner Join sys.query_store_runtime_stats AS rs1
ON p1.plan_id = rs1.plan_id
Inner Join sys.query_store_runtime_stats_interval AS rsi1
ON rsi1.runtime_stats_interval_id = rs1.runtime_stats_interval_id
Inner Join sys.query_store_plan AS p2
ON q.query_id = p2.query_id
Inner Join sys.query_store_runtime_stats AS rs2
ON p2.plan_id = rs2.plan_id
Inner Join sys.query_store_runtime_stats_interval AS rsi2
ON rsi2.runtime_stats_interval_id = rs2.runtime_stats_interval_id
Where rsi1.start_time > DATEADD(hour, -48, GETUTCDATE())
AND rsi2.start_time > rsi1.start_time
AND p1.plan_id <> p2.plan_id
AND rs2.avg_duration > rs1.avg_duration * 2
Order By q.query_id, rsi1.start_time, rsi2.start_time
Impostazioni e informazioni:
- SQL Server 2016 SP1 CU4 Enterprise su un cluster Windows Server 2012R2
- Archivio query abilitato e configurato come predefinito (nessuna impostazione modificata)
- database importato da un'istanza di SQL 2005 (e ancora al livello di compatibilità 100)
Osservazione empirica:
- a causa di statistiche estremamente stravaganti, abbiamo preso tutti gli oggetti * plan_persist ** utilizzati nel piano stimato errato (nessun piano reale ancora, causa l'interruzione della query) e controllato le statistiche, alcuni degli indici utilizzati nel piano non avevano alcuna statistica (DBCC SHOWSTATISTICS non ha restituito nulla, selezionare da sys.stats ha mostrato la funzione NULL stats_date () per alcuni indici
Soluzione rapida e sporca:
- creare manualmente statistiche mancanti su oggetti di sistema relativi a Query Store o
- forzare l'esecuzione della query utilizzando il nuovo CE (traceflag), che creerà / aggiornerà anche le statistiche necessarie o
- modificare il livello di compatibilità del database su 130 (quindi per impostazione predefinita utilizzerà il nuovo CE)
Quindi, la mia vera domanda sarebbe:
Perché una query su Query Store potrebbe causare problemi di prestazioni sull'intera istanza? Siamo in un territorio di bug con Query Store?
PS: caricherò alcuni file (schermate di stampa, statistiche IO e piani) in breve tempo.
File aggiunti su Dropbox .
Piano 1 - piano iniziale stravagante stimato in produzione
Piano 2 - piano attuale, vecchio CE, in un ambiente di prova (stesso comportamento, stesse statistiche stravaganti)
Piano 3 - piano effettivo, nuovo CE, in un ambiente di prova