Я думаю про ситуацію, коли у мене є дві колонки з високою щільністю, але ці стовпці не є незалежними.
Визначення
Ось це визначення таблиці, яку я створив для цілей тестування.
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