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

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

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. Когда я создал отфильтрованную статистику в соответствии с автором, я мог правильно видеть оценки, но зачем нам создавать отфильтрованную статистику, как я могу сказать, что мне нужна отфильтрованная статистика для моих запросов, поскольку даже когда я создал простую статистику, я получил тот же результат.

Лучшее, что я когда-либо встречал 1. Кимберли Трипп искажает видео со статистикой
2. Информационный документ о статистике Technet

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

заранее спасибо. Обновление: 4 июля

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

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

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

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

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

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


person TheGameiswar    schedule 28.06.2015    source источник
comment
Это объясняется в статье, не так ли? What happened here is the filtered statistics (create statistics Region_stats_id on Region (id) where name = 'Dallas') is used for optimization. When SQL optimizes the query, it sees there is a statistics that matches the where clause. It then discovers there is only 1 id of 0 and thus is able to do a correct estimate.   -  person Martin Smith    schedule 28.06.2015


Ответы (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 (для Далласа) 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 знает, что существует только 1 строка с идентификатором 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 за сегодняшний день, но уже удалил себя.

person James Z    schedule 28.06.2015