le statistiche sono aggiornate, ma la stima non è corretta


12

Quando lo faccio dbcc show_statistics ('Reports_Documents', PK_Reports_Documents)ottengo il seguente risultato per l'ID report 18698:

inserisci qui la descrizione dell'immagine

Per questa query:

SELECT * 
FROM Reports_Documents 
WHERE ReportID = 18698 option (recompile)

Ottengo un piano di query che consente di cercare un indice cluster PK_Reports_Documentscome previsto.

Ma ciò che mi sconcerta è il valore errato per il numero stimato di righe:

inserisci qui la descrizione dell'immagine

Secondo questo :

Quando il valore della clausola WHERE della query di esempio è uguale a un valore RANGE_HI_KEY dell'istogramma, SQL Server utilizzerà la colonna EQ_ROWS nell'istogramma per determinare il numero di righe uguali a

Questo è anche il modo in cui mi aspetterei che fosse, tuttavia sembra non essere il caso nella vita reale. Ho anche provato alcuni altri RANGE_HI_KEYvalori presenti nell'istogramma fornito show_statisticse sperimentato lo stesso. Questo problema nel mio caso sembra causare alcune query che utilizzano piani di esecuzione molto non ottimali con conseguente tempo di esecuzione di alcuni minuti mentre riesco a farlo funzionare in 1 secondo con un suggerimento di query.

Tutto sommato: qualcuno può spiegarmi perché EQ_ROWSdall'istogramma non viene utilizzato per il numero stimato di righe e da dove proviene la stima errata?

Altre informazioni (forse utili):

  • La creazione automatica delle statistiche è attiva e tutte le statistiche sono aggiornate.
  • La tabella interrogata ha circa 80 milioni di righe.
  • PK_Reports_Documentsè una combinazione PK composta da ReportID INTeDocumentID CHAR(8)

La query sembra caricare un totale di 5 diversi oggetti statistici, ognuno dei quali contiene ReportID+ alcune altre colonne della tabella. Sono stati tutti aggiornati di recente. RANGE_HI_KEYnella tabella seguente è il valore della colonna con limite superiore più alto nell'istogramma.

+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+
|                                  name                                   | stats_id | auto_created | user_created | Leading column Type | RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS  | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+
| PK_Reports_Documents                                                    |        1 |            0 |            0 | Stationary          |        18722 | 0          | 2228,526 |                   0 | 1              |
| _dta_index_Reports_Documents_42_1629248859__K1_K63_K14_K13_K22_K23_72_6 |       62 |            0 |            0 | Stationary          |        18698 | 0          | 2228,526 |                   0 | 1              |
| _dta_stat_1629248859_1_1_59                                             |       76 |            0 |            1 | Stationary          |        18686 | 50,56393   | 1        |                   0 | 13397,04       |
| _dta_stat_1629248859_1_22_14_18_12_6                                    |       95 |            0 |            1 | Stationary          |        18698 | 0          | 2228,526 |                   0 | 1              |
| _dta_stat_1629248859_1_7_14_4_23_62                                     |       96 |            0 |            1 | Stationary          |        18698 | 56,63327   | 21641,5  |                   0 | 14526,44       |
+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+

sp_updatestats è programmato per funzionare ogni notte per aggiornare le statistiche.

Risposte:


10

C'è una soluzione semplice a questo:

Elimina tutte le _dta_...statistiche e smetti di applicare ciecamente le raccomandazioni DTA.

Maggiori informazioni

Il problema particolare era che c'erano più serie di statistiche per la colonna in questione. Le dtastatistiche extra sono state create campionando i dati (il comportamento predefinito per le statistiche non associate a un indice).

Come spesso accade con le statistiche campionate, gli istogrammi risultanti non coprivano l'intera gamma dei dati non coerenti. La query nella domanda è riuscita a scegliere un valore esterno all'istogramma, risultando in una stima a 1 riga.

L'esatto comportamento di Query Optimizer in presenza di più insiemi di statistiche per la stessa colonna non è completamente documentato. Preferisce preferire le statistiche di "scansione completa" rispetto a quelle campionate, ma preferisce anche le statistiche aggiornate più di recente a quelle più vecchie.


Questo funziona davvero. Tuttavia non ho creato le _dta_statistiche, erano lì da quando ho avuto la mia prima occhiata sul DB. Non sapevo che usare le raccomandazioni potesse avere effetti così negativi ...
user1151923
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.