Estoy pensando en una situación en la que tengo dos columnas con alta densidad pero estas columnas no son independientes.
Definición
Aquí está la definición de la tabla que he creado para fines de prueba.
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]
Datos
Los datos para el experimento son los siguientes
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
Paso 1: filtrado por col1
SELECT * FROM StatsTest WHERE col1=1
Como se esperaba, el Optimizador de consultas adivina el número exacto de filas.
Paso 2: filtrado por col2
SELECT * FROM StatsTest WHERE col2=1
Nuevamente tenemos una estimación perfecta.
Paso 3: filtrado por col1 y col2
SELECT * FROM StatsTest WHERE col1=1 AND col2=1
Aquí la estimación está lejos de estar cerca del número real de filas.
El problema es que la implicidad del analizador de consultas supone que col1 y col2 son independientes pero no lo son.
Paso 4: filtrado por col4
SELECT * FROM StatsTest WHERE col4 = 11
Puedo filtrar por col4 = 11 para obtener los mismos resultados que la consulta en el Paso 3, porque col4 es una columna calculada y de acuerdo con la forma en que se ha definido col1 = 1 y col2 = 1 es equivalente a col4 = 11 Aquí, sin embargo , como se esperaba, la estimación es perfecta.
Conclusión / Pregunta
¿Es esta solución artificial y poco elegante la única opción disponible para lograr estimaciones precisas cuando se trata de filtrar por dos o más columnas no independientes? ¿La columna calculada y el filtro por la columna calculada son estrictamente necesarios para obtener una precisión real?
Ejemplo en sqlfiddle