The*_*war 14 sql-server performance query-tuning sql-server-2012
我正在通过以下链接过滤过滤统计数据.
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
Run Code Online (Sandbox Code Playgroud)
我的问题是我们在两个表格中都有以下统计数据
sp_helpstats 'region','all'
sp_helpstats 'sales','all'
Run Code Online (Sandbox Code Playgroud)
表区域:
statistics_name statistics_keys
d1 id
ix_Region_id_name id, name
ix_Region_name name
Run Code Online (Sandbox Code Playgroud)
表销售额:
statistics_name statistics_keys
ix_Sales_id_detail id, detail
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
2.当我根据作者创建过滤统计数据时,我可以正确地看到估计值,但为什么我们需要创建过滤统计数据,我怎么说我需要过滤统计数据用于我的查询,因为即使我创建简单的统计数据,我也得到相同的结果.
到目前为止我遇到的最好的1.Kimberely tripp skewed stats video
2.Technet stats whitepaper
但仍然无法理解为什么过滤后的数据在这里有所不同
提前致谢. 更新:7/4
在马丁和詹姆斯回答之后重述这个问题:
1.
除了kimberely脚本之外,还有什么方法可以避免数据偏差,另一种估算方法是计算值的行数.
2.您遇到任何与数据偏差有关的问题.我认为这取决于大桌子.但我正在寻找一些详细的答案
3.我们必须采取sql的IO成本来扫描表格,并且有时会对触发更新stats时的查询进行一些阻塞.除了这一点,你还可以看到维护统计数据的任何开销.
原因是我正在考虑根据基于DTA输入的几个条件创建压缩统计数据.
再次感谢
我想这就是它发生的原因.您获得相同的估计(500.5)行,因为SQL Server没有统计信息可以告知哪些ID是与哪个区域相关的ID.统计信息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
Run Code Online (Sandbox Code Playgroud)
所以这告诉每个ID有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
Run Code Online (Sandbox Code Playgroud)
所以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
Run Code Online (Sandbox Code Playgroud)
销售额中的行数在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
Run Code Online (Sandbox Code Playgroud)
信息:这是@MartijnPieters删除的答案的副本,因为这是我打算回答的问题 - 我似乎无法对删除的答案做任何事情.我从今天开始不小心写了这个给TheGameiswar的其他统计问题,但我已经删除了自己.
归档时间: |
|
查看次数: |
618 次 |
最近记录: |