Perché SQL Server non esegue istogrammi statistici composti di colonne?


10

SQL Server ha una cosa chiamata "statistiche multi-colonna", ma non è ciò che si pensa significherebbe.

Diamo un'occhiata alla seguente tabella di esempio:

CREATE TABLE BadStatistics 
(
    IsArchived BIT NOT NULL,
    Id INT NOT NULL IDENTITY PRIMARY KEY,
    Mystery VARCHAR(200) NOT NULL
);

CREATE NONCLUSTERED INDEX BadIndex 
    ON BadStatistics (IsArchived, Mystery);

Con ciò, due statistiche vengono create sui due indici che abbiamo:

Statistiche per BadIndex:

+--------------+----------------+-------------------------+
| All density  | Average Length | Columns                 |
+--------------+----------------+-------------------------+
| 0.5          | 1              | IsArchived              |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 37             | IsArchived, Mystery     |
+--------------+----------------+-------------------------+
| 4.149378E-06 | 41             | IsArchived, Mystery, Id |
+--------------+----------------+-------------------------+

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 0            | 0          | 24398   | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+
| 1            | 0          | 216602  | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+

Statistiche per indice cluster:

+--------------+----------------+---------+
| All density  | Average Length | Columns |
+--------------+----------------+---------+
| 4.149378E-06 | 4              | Id      |
+--------------+----------------+---------+

+--------------+------------+---------+---------------------+----------------+
| RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+--------------+------------+---------+---------------------+----------------+
| 1            | 0          | 1       | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+
| 240999       | 240997     | 1       | 240997              | 1              |
+--------------+------------+---------+---------------------+----------------+
| 241000       | 0          | 1       | 0                   | 1              |
+--------------+------------+---------+---------------------+----------------+

(Ho popolato la tabella con dati di esempio casuali in cui circa un decimo delle righe non sono archiviate. Successivamente ho eseguito un aggiornamento completo delle statistiche di scansione.)

Perché l'istogramma delle statistiche a due colonne utilizza solo una colonna? So che molte persone hanno scritto che fa , ma qual è la logica? In questo caso, rende l'intero istogramma molto meno utile, poiché la prima colonna ha sempre solo due valori. Perché le statistiche dovrebbero essere arbitrariamente limitate in questo modo?

Si noti che questa domanda non si riferisce agli istogrammi multidimensionali, che sono una bestia completamente diversa. Si tratta di istogrammi monodimensionali con la singola dimensione che sono le tuple contenenti le rispettive colonne multiple.

Risposte:


8

sfondo

L'attuale modello di SQL Server utilizza solo istogrammi a colonna singola e informazioni sulla densità a più colonne. Istogrammi colonna singola sono utilizzati per stimare selettività per predicati adatti pe a = 1o b > 50. Una query con più predicati combina semplicemente le singole selettività (con ipotesi) per produrre una selettività complessiva stimata.

Per un esempio, vedere il mio articolo Stima della cardinalità: combinazione delle statistiche della densità

La densità multi-colonna informa ulteriormente il modello fornendo informazioni di correlazione debole per predicati di uguaglianza multipla e raggruppando cardinalità per aggregazioni.

Le statistiche associate agli indici sono un'aggiunta opportunistica a quel modello: il motore potrebbe anche raccogliere statistiche (normalmente a scansione completa) mentre sta costruendo un indice. SQL Server crea automaticamente un istogramma della colonna principale e informazioni sulla densità per le altre chiavi.

Gli istogrammi per colonne non iniziali in un indice possono essere creati automaticamente su richiesta dal processore di query o in anticipo utilizzando sp_createstatsl' @indexonlyopzione (tra gli altri).

Istogrammi a più colonne

Le ipotesi formulate quando si combinano statistiche a colonna singola (come sopra) possono o meno modellare abbastanza bene la realtà dei dati. In molti casi, le opzioni disponibili (backoff esponenziale, indipendenza, selettività minima) producono una stima "abbastanza buona".

Abbiamo anche filtrato le statistiche (e gli indici) come soluzione naturale agli indici delle colonne principali a bassa cardinalità come nell'esempio della domanda. Portarli all'estremo logico ci porta più vicini alle statistiche multidimensionali di cui la domanda non tratta.

Quando le opzioni di modellazione disponibili non sono in grado di fornire una stima adeguata, un istogramma statistico a più colonne potrebbe effettivamente fornire una migliore stima della selettività per predicati dell'indice idonei, in alcuni casi. Ci sono alcune difficoltà nel combinare tipi di dati diversi in colonne diverse, ma nulla di insormontabile.

Avremmo anche bisogno di un istogramma per ogni livello delle chiavi di indice (per i migliori risultati); quindi per un indice su (a, b, c)ciò significherebbe istogrammi su (a, b)e (a, b, c)in aggiunta all'attuale istogramma a colonna singola su (a)solo.

Il meccanismo utilizzato per rilevare le statistiche obsolete dovrebbe anche essere modificato per mantenere gli istogrammi multi-colonna interessati. Questi istogrammi finiranno probabilmente per essere ricostruiti più spesso delle statistiche a colonna singola, semplicemente perché le modifiche a più colonne li riguardano.

Tutto ciò aggiunge dimensioni, complessità e costi generali di manutenzione.

Le statistiche multi-colonna possono essere simulate (in misura limitata) usando una statistica creata su una colonna calcolata attentamente costruita che fa riferimento a più colonne. La query dovrebbe includere un predicato nella colonna calcolata (o una corrispondenza testuale esatta per la formula sottostante) per sfruttare questa statistica. Probabilmente ci sono solo situazioni molto limitate in cui questo approccio è pratico. Tuttavia, presenta alcuni degli stessi problemi di implementazione degli istogrammi automatici a più colonne.

In definitiva, le uniche persone che potrebbero dire con certezza perché SQL Server non supporta le statistiche multi-colonna sarebbero i progettisti stessi. Se ritieni di poter fare una valida causa per un miglioramento del prodotto in questo settore con ampia applicabilità, potresti suggerirlo su Connect o tramite il tuo normale canale di supporto.

Nota

In questo caso, rende l'intero istogramma molto meno utile, poiché la prima colonna ha sempre solo due valori

L'istogramma fornisce ancora informazioni utili sulla distribuzione dei valori nella colonna principale: quando sono state create le statistiche, c'erano 24.398 righe dove IsArchivedera falso e 216.602 righe dove era vero .

Inoltre, l'oggetto statistico ci dice che ci sono (1 / 0,5) = 2 valori distinti per IsArchived, (1 / 4.149378E-06) ~ = 241000 valori distinti per (IsArchived, Mystery)con una dimensione media della riga di 37 byte e la stessa frequenza per (IsArchived, Mystery, Id)con 4 byte extra per riga.

Sono tutte buone informazioni di carattere generale, che possono essere combinate con informazioni statistiche su altre colonne per produrre una stima della selettività in query con predicati multipli (come menzionato).

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.