Я просматривал отфильтрованную статистику по ссылке ниже.
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.
еще раз спасибо
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