Sto pensando a una situazione in cui ho due colonne ad alta densità ma queste colonne non sono indipendenti.
Definizione
Ecco la definizione della tabella che ho creato a scopo di test.
CREATE TABLE [dbo].[StatsTest](
[col1] [int] NOT NULL, --can take values 1 and 2 only
[col2] [int] NOT NULL, --can take integer values from 1 to 4 only
[col3] [int] NOT NULL, --integer. it has not relevance just to ensure that each row is different
[col4] AS ((10)*[col1]+[col2]) --a computed column ensuring that if two rows have different values in col1 or col2 have different values in col4
) ON [PRIMARY]
Dati
I dati per l'esperimento sono i seguenti
col1 col2 col3 col4
1 1 1 11
1 2 2 12
1 2 3 12
1 3 4 13
1 3 5 13
1 3 6 13
1 4 7 14
1 4 8 14
1 4 9 14
1 4 10 14
2 1 11 21
2 1 12 21
2 1 13 21
2 1 14 21
2 2 15 22
2 2 16 22
2 2 17 22
2 3 18 23
2 3 19 23
2 4 20 24
Passaggio 1: filtro per col1
SELECT * FROM StatsTest WHERE col1=1
Come previsto, lo Strumento per ottimizzare le query indovina il numero esatto di righe.
Passaggio 2: filtro per col2
SELECT * FROM StatsTest WHERE col2=1
Ancora una volta abbiamo una stima perfetta.
Passaggio 3: filtro per col1 e col2
SELECT * FROM StatsTest WHERE col1=1 AND col2=1
Qui la stima è lungi dall'essere vicina al numero effettivo di righe.
Il problema è che l'implicazione dell'analizzatore di query presuppone che col1 e col2 siano indipendenti ma non lo sono.
Passaggio 4: filtro per col4
SELECT * FROM StatsTest WHERE col4 = 11
Posso filtrare per col4 = 11 per ottenere gli stessi risultati della query nel passaggio 3, perché col4 è una colonna calcolata e in base al modo in cui è stata definita col1 = 1 e col2 = 1 è equivalente a col4 = 11 Qui, tuttavia , come previsto, la stima è perfetta.
Conclusione / Domanda
¿Questa soluzione artificiale e non elegante è l'unica opzione disponibile per ottenere stime accurate quando si tratta di filtrare per due o più colonne non indipendenti? ¿La colonna calcolata e il filtro della colonna calcolata sono strettamente necessari per ottenere la precisione effettiva?
Esempio in sqlfiddle