Случай использования фильтрованной статистики

Я просмотрел отфильтрованные данные в ссылке ниже.

http://blogs.msdn.com/b/psssql/archive/2010/09/28/case-of-using-filtered-statistics.aspx

Данные сильно искажены, одна область имеет 0 строк, остальные - из разных областей. Ниже приведен весь код для воспроизведения проблемы.

create table Region(id int, name nvarchar(100)) 
go 
create table Sales(id int, detail int) 
go 
create clustered index d1 on Region(id) 
go 
create index ix_Region_name on Region(name) 
go 
create statistics ix_Region_id_name on Region(id, name) 
go 
create clustered index ix_Sales_id_detail on Sales(id, detail) 
go

-- only two values in this table as lookup or dim table 
insert Region values(0, 'Dallas') 
insert Region values(1, 'New York') 
go

set nocount on 
-- Sales is skewed 
insert Sales values(0, 0) 
declare @i int 
set @i = 1 
while @i <= 1000 begin 
insert Sales  values (1, @i) 
set @i = @i + 1 
end 
go

update statistics Region with fullscan 
update statistics Sales with fullscan 
go

set statistics profile on 
go 
--note that this query will over estimate 
-- it estimate there will be 500.5 rows 
select detail from Region join Sales on Region.id = Sales.id where name='Dallas' option (recompile) 
--this query will under estimate 
-- this query will also estimate 500.5 rows in fact 1000 rows returned 
select detail from Region join Sales on Region.id = Sales.id where name='New York' option (recompile) 
go

set statistics profile off 
go

create statistics Region_stats_id on Region (id) 
where name = 'Dallas' 
go 
create statistics  Region_stats_id2 on Region (id) 
where name = 'New York' 
go

set statistics profile on 
go 
--now the estimate becomes accurate (1 row) because 
select detail from Region join Sales on Region.id = Sales.id where name='Dallas' option (recompile)

--the estimate becomes accurate (1000 rows) because stats Region_stats_id2 is used to evaluate 
select detail from Region join Sales on Region.id = Sales.id where name='New York' option (recompile) 
go

set statistics profile off

Мой вопрос заключается в том, что мы имеем ниже статистики, доступные в обеих таблицах

sp_helpstats 'region','all'
sp_helpstats 'sales','all'

Область таблицы:

statistics_name   statistics_keys
d1                    id
ix_Region_id_name     id, name
ix_Region_name        name

Продажа таблиц:

statistics_name    statistics_keys
ix_Sales_id_detail     id, detail

1.Почему оценка пошла не так для следующих запросов

select detail from Region join Sales on Region.id = Sales.id where name='Dallas' option (recompile)

--the estimate becomes accurate (1000 rows) because stats Region_stats_id2 is used to evaluate 
select detail from Region join Sales on Region.id = Sales.id where name='New York' option (recompile) 

2.Когда я создал отфильтрованный stat в соответствии с автором, я мог видеть оценки правильно, но почему нам нужно создавать отфильтрованные статистические данные, как я могу сказать, что мне нужно фильтровать статистику для моих запросов, так как даже когда я создал простую статистику, я получил тот же результат.

Лучше всего я натолкнулся 1.Компьютерная искаженная статистика 2.Технологическая статистика

Но все еще не в состоянии понять, почему отфильтрованные данные здесь имеют значение

Заранее спасибо. Обновление: 7/4

Перефразируя вопрос после ответов Мартина и Джеймса:

1.Есть ли способ избежать перекос данных кроме kimberely script, еще один способ оценить - подсчитать количество строк для значения.

2. Вы столкнулись с какими-либо проблемами с перекосом данных в своем опыте. Я полагаю, что это зависит от больших таблиц. Но я ищу подробный ответ

3. Мы должны брать стоимость ввода-вывода для sql для сканирования таблицы и вместе с некоторыми блокированиями иногда для запроса, который выпадает во время запуска статистики обновления. Если вы видите какие-либо накладные расходы, кроме этого, при сохранении статистики.

Причина в том, что я собираюсь создать файловую статистику на основе нескольких условий, основанных на вводе DTA.

еще раз спасибо

Ответы

Ответ 1

Я бы предположил, что это так. Вы получаете те же самые оценки (500.5), потому что у этого SQL Server нет статистики, которая бы указывала, какие идентификаторы являются теми, которые связаны с каким регионом. У статистики ix_Region_id_name есть оба поля, но поскольку гистограмма существует только для первого столбца, это действительно не помогает в оценках относительно того, сколько строк будет в таблице Sales.

Если вы запустите dbcc show_statistics ('Region','ix_Region_id_name'), результатом будет:

RANGE_HI_KEY   RANGE_ROWS   EQ_ROWS   DISTINCT_RANGE_ROWS   AVG_RANGE_ROWS
0              0            1         0                     1
1              0            1         0                     1

Итак, это говорит о том, что для каждого идентификатора есть 1 строка, но нет ссылки на имена.

Но когда вы создаете статистику Region_stats_id (для Dallas), dbcc show_statistics ('Region','Region_stats_id') покажет:

RANGE_HI_KEY   RANGE_ROWS   EQ_ROWS   DISTINCT_RANGE_ROWS   AVG_RANGE_ROWS
0              0            1         0                     1

Итак, SQL Server знает, что существует только одна строка, а ID 0.

Аналогично Region_stats_id2:

RANGE_HI_KEY   RANGE_ROWS   EQ_ROWS   DISTINCT_RANGE_ROWS   AVG_RANGE_ROWS
1              0            1         0                     1

И количество строк в продажах в ix_Sales_id_detail поможет определить строки на ID:

RANGE_HI_KEY   RANGE_ROWS   EQ_ROWS   DISTINCT_RANGE_ROWS   AVG_RANGE_ROWS
0              0            1         0                     1
1              0            1000      0                     1

Информация: теперь это копия ответа, удаленная @MartijnPieters, потому что это вопрос, на который я собирался ответить - и я не могу ничего сделать с удаленным ответом. Я случайно написал это первым в TheGameiswar другой вопрос статистики с сегодняшнего дня, но я уже удалил себя.