SQL Server 索引与统计

Sco*_*ott 14 index sql-server statistics

之间有什么区别CREATE INDEXCREATE STATISTICS何时该使用的呢?

Tho*_*ger 20

索引存储实际数据(数据页或索引页取决于我们所谈论的索引类型),而统计信息存储数据分布。因此,CREATE INDEX将使用 DDL 创建索引(聚簇、非聚簇等),CREATE STATISTICS并使用 DDL 创建表内列的统计信息。

我建议您阅读有关关系数据的这些方面的内容。下面是一些初学者的介绍性文章。这些是非常广泛的主题,因此有关它们的信息可以非常广泛和深入。阅读下面它们的总体思路,并在它们出现时提出更具体的问题。

表和索引组织的
BOL 参考 BOL 聚集索引结构的
参考 BOL 非聚集索引结构的参考
SQL Server Central 索引简介
BOL 参考统计

这是一个工作示例,可以查看这两个部分的实际操作(注释以进行解释):

use testdb;
go

create table MyTable1
(
    id int identity(1, 1) not null,
    my_int_col int not null
);
go

insert into MyTable1(my_int_col)
values(1);
go 100

-- this statement will create a clustered index
-- on MyTable1.  The index key is the id field
-- but due to the nature of a clustered index
-- it will contain all of the table data
create clustered index MyTable1_CI
on MyTable1(id);
go


-- by default, SQL Server will create a statistics
-- on this index.  Here is proof.  We see a stat created
-- with the name of the index, and the consisting stat 
-- column of the index key column
select
    s.name as stats_name,
    c.name as column_name
from sys.stats s
inner join sys.stats_columns sc
on s.object_id = sc.object_id
and s.stats_id = sc.stats_id
inner join sys.columns c
on sc.object_id = c.object_id
and sc.column_id = c.column_id
where s.object_id = object_id('MyTable1');


-- here is a standalone statistics on a single column
create statistics MyTable1_MyIntCol
on MyTable1(my_int_col);
go

-- now look at the statistics that exist on the table.
-- we have the additional statistics that's not necessarily
-- corresponding to an index
select
    s.name as stats_name,
    c.name as column_name
from sys.stats s
inner join sys.stats_columns sc
on s.object_id = sc.object_id
and s.stats_id = sc.stats_id
inner join sys.columns c
on sc.object_id = c.object_id
and sc.column_id = c.column_id
where s.object_id = object_id('MyTable1');


-- what is a stat look like?  run DBCC SHOW_STATISTICS
-- to get a better idea of what is stored
dbcc show_statistics('MyTable1', 'MyTable1_CI');
go
Run Code Online (Sandbox Code Playgroud)

以下是统计测试样本的样子:

在此处输入图片说明

请注意,统计数据是数据分布的包含。它们帮助 SQL Server 确定最佳计划。一个很好的例子是,想象一下你要承受一个重物。如果你知道重量是多少,因为上面有重量标记,你就可以确定最好的举重方式和肌肉。这就是 SQL Server 对统计数据所做的工作。

-- create a nonclustered index
-- with the key column as my_int_col
create index IX_MyTable1_MyIntCol
on MyTable1(my_int_col);
go

-- let's look at this index
select
    object_name(object_id) as object_name,
    name as index_name,
    index_id,
    type_desc,
    is_unique,
    fill_factor
from sys.indexes
where name = 'IX_MyTable1_MyIntCol';

-- now let's see some physical aspects
-- of this particular index
-- (I retrieved index_id from the above query)
select *
from sys.dm_db_index_physical_stats
(
    db_id('TestDB'),
    object_id('MyTable1'),
    4,
    null,
    'detailed'
);
Run Code Online (Sandbox Code Playgroud)

从上面的例子我们可以看出,索引实际上包含了数据(根据索引的类型,叶子页会有所不同)。

本帖仅显示一个非常非常非常简短的这两个概述方面的SQL Server。这两者都可以占用章节和书籍。阅读一些参考资料,然后你会更好地掌握。

  • 我知道这是一篇旧帖子,但我认为值得注意的是,创建索引将(在大多数情况下)自动生成索引的统计信息。不能说创建统计数据也是如此。 (2认同)