Ich denke an eine Situation, in der ich zwei Spalten mit hoher Dichte habe, aber diese Spalten nicht unabhängig sind.
Definition
Hier ist die Definition der Tabelle, die ich zu Testzwecken erstellt habe.
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]
Daten
Die Daten für das Experiment sind die folgenden
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
Schritt 1: Filtern nach col1
SELECT * FROM StatsTest WHERE col1=1
Wie erwartet schätzt das Abfrageoptimierungsprogramm die genaue Anzahl der Zeilen.
Schritt 2: Filtern nach col2
SELECT * FROM StatsTest WHERE col2=1
Wieder haben wir eine perfekte Schätzung.
Schritt 3: Filtern nach col1 und col2
SELECT * FROM StatsTest WHERE col1=1 AND col2=1
Hier ist die Schätzung weit davon entfernt, der tatsächlichen Anzahl von Zeilen nahe zu kommen.
Das Problem besteht darin, dass die implizite Annahme des Abfrageanalysators lautet, dass col1 und col2 unabhängig sind, dies jedoch nicht.
Schritt 4: Filtern nach col4
SELECT * FROM StatsTest WHERE col4 = 11
I kann durch col4 Filter = 11 die gleichen Ergebnisse wie die Abfrage in Schritt 3 zu bekommen, weil col4 eine berechnete Spalte ist und entsprechend die Art und Weise definiert worden spalte1 = 1 und Col2 = 1 entsprechen col4 = 11 hier jedoch Wie erwartet ist die Schätzung perfekt.
Fazit / Frage
¿Ist diese künstliche und unelegante Lösung die einzige verfügbare Option, um beim Filtern nach zwei oder mehr nicht unabhängigen Spalten genaue Schätzungen zu erzielen? ¿Sind die berechnete Spalte und der Filter für die berechnete Spalte unbedingt erforderlich, um die tatsächliche Genauigkeit zu erzielen?
Beispiel in sqlfiddle