使用过滤统计的案例
Case of using filtered statistics
我正在浏览下面 link 中的过滤统计数据。
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
我的问题是我们在 tables
上都有以下统计数据
sp_helpstats 'region','all'
sp_helpstats 'sales','all'
Table地区:
statistics_name statistics_keys
d1 id
ix_Region_id_name id, name
ix_Region_name name
Table 销售额:
statistics_name statistics_keys
ix_Sales_id_detail id, detail
1.Why 以下查询的估计出错了
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.When 我根据作者创建了过滤统计信息,我可以正确地看到估计值,但是为什么我们需要创建过滤统计信息,我怎么能说我的查询需要过滤统计信息,因为即使我创建了简单的统计信息统计数据,我得到了相同的结果。
到目前为止我遇到的最好的
1.Kimberely tripp 偏斜统计视频
2.Technet 统计白皮书
但仍然无法理解为什么过滤后的统计数据会有所不同
提前致谢。
更新时间:7/4
在马丁和詹姆斯回答后改写问题:
1.Is有什么方法可以避免数据偏斜
除了 kimberely 脚本,另一种估计方法是计算值的行数。
2.Have 你在你的 experience.I 中遇到了任何数据偏斜的问题假设它取决于大 tables.But 我正在寻找一些详细的答案
3.We 必须承担 sql 的 IO 成本来扫描 table 并且有时会在触发更新时遇到一些阻塞 stats.do 你会看到除此之外的任何维护统计数据的开销。
原因是我也在考虑基于 DTA 输入的几个条件创建过滤统计数据。
再次感谢
我想这就是它发生的原因。您得到相同的估计 (500.5) 行,因为 SQL 服务器没有统计信息可以告诉哪些 ID 与哪个区域相关。统计数据 ix_Region_id_name 有两个字段,但由于直方图仅存在于第一列,因此它确实无助于估计 Sales table.
中的行数
如果你运行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
所以这表明每个 ID 有 1 行,但是名称没有 link。
但是当您创建统计信息时 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服务器知道只有1行,它的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 的其他统计问题上,但我已经删除了自己。
我正在浏览下面 link 中的过滤统计数据。
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
我的问题是我们在 tables
上都有以下统计数据sp_helpstats 'region','all'
sp_helpstats 'sales','all'
Table地区:
statistics_name statistics_keys
d1 id
ix_Region_id_name id, name
ix_Region_name name
Table 销售额:
statistics_name statistics_keys
ix_Sales_id_detail id, detail
1.Why 以下查询的估计出错了
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.When 我根据作者创建了过滤统计信息,我可以正确地看到估计值,但是为什么我们需要创建过滤统计信息,我怎么能说我的查询需要过滤统计信息,因为即使我创建了简单的统计信息统计数据,我得到了相同的结果。
到目前为止我遇到的最好的
1.Kimberely tripp 偏斜统计视频
2.Technet 统计白皮书
但仍然无法理解为什么过滤后的统计数据会有所不同
提前致谢。 更新时间:7/4
在马丁和詹姆斯回答后改写问题:
1.Is有什么方法可以避免数据偏斜
除了 kimberely 脚本,另一种估计方法是计算值的行数。
2.Have 你在你的 experience.I 中遇到了任何数据偏斜的问题假设它取决于大 tables.But 我正在寻找一些详细的答案
3.We 必须承担 sql 的 IO 成本来扫描 table 并且有时会在触发更新时遇到一些阻塞 stats.do 你会看到除此之外的任何维护统计数据的开销。
原因是我也在考虑基于 DTA 输入的几个条件创建过滤统计数据。
再次感谢
我想这就是它发生的原因。您得到相同的估计 (500.5) 行,因为 SQL 服务器没有统计信息可以告诉哪些 ID 与哪个区域相关。统计数据 ix_Region_id_name 有两个字段,但由于直方图仅存在于第一列,因此它确实无助于估计 Sales table.
中的行数如果你运行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
所以这表明每个 ID 有 1 行,但是名称没有 link。
但是当您创建统计信息时 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服务器知道只有1行,它的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 的其他统计问题上,但我已经删除了自己。