Я имею в виду ситуацию, когда у меня есть два столбца с высокой плотностью, но эти столбцы не являются независимыми.
Определение
Вот определение таблицы, которую я создал для целей тестирования.
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]
Данные
Данные для эксперимента следующие
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
Шаг 1: Фильтрация по col1
SELECT * FROM StatsTest WHERE col1=1
Как и ожидалось, оптимизатор запросов угадывает точное количество строк.
Шаг 2: Фильтрация по col2
SELECT * FROM StatsTest WHERE col2=1
Снова у нас есть прекрасная оценка.
Шаг 3: Фильтрация по col1 и col2
SELECT * FROM StatsTest WHERE col1=1 AND col2=1
Здесь оценка далека от фактического количества строк.
Проблема заключается в том, что простота анализатора запросов предполагает, что col1 и col2 независимы, но это не так.
Шаг 4: Фильтрация по col4
SELECT * FROM StatsTest WHERE col4 = 11
Я могу отфильтровать по col4 = 11, чтобы получить те же результаты, что и запрос в шаге 3, потому что col4 является вычисляемым столбцом и в соответствии с тем, как он был определен, col1 = 1, а col2 = 1 эквивалентно col4 = 11. Однако здесь , как и ожидалось, оценка идеальна.
Заключение / Вопрос
¿Является ли это искусственное и не элегантное решение единственным доступным вариантом для достижения точных оценок при работе с фильтрацией по двум или более независимым столбцам? ¿Является ли вычисляемый столбец и фильтр по вычисляемому столбцу крайне необходимыми для получения фактической точности?
Пример в sqlfiddle