SQL统计和索引 - 它们有多详细?

时间:2010-10-22 17:17:50

标签: sql-server statistics performance

统计数据(有助于决定是否使用索引)会考虑每实际列值的行数,还是只使用平均值每个值的行数。

假设我有一个名为active的位列的表,它有一百万行,但99.99%设置为false。如果我在这个列上有一个索引,那么Sql足够智能,如果搜索active = 1就知道使用索引但是如果搜索active = 0则没有意义。

另一个例子,如果我有一个表,其中包含一个索引列的1,000,000条记录,其中包含大约50,000个不同的值,每个值的平均行数为10,但是有一个特殊值,其中包含500,000行。如果搜索此特殊记录,索引可能没用,但在查找任何其他代码时非常有用。

但这种特殊情况是否会破坏指数的有效性。

3 个答案:

答案 0 :(得分:3)

你可以亲眼看看:

CREATE TABLE IndexTest (
Id int not null primary key identity(1,1),
Active bit not null default(0),
IndexedValue nvarchar(10) not null
)

CREATE INDEX IndexTestActive ON IndexTest (Active)
CREATE INDEX IndexTestIndexedValue ON IndexTest (IndexedValue)

DECLARE @values table
(
    Id int primary key IDENTITY(1, 1),
    Value nvarchar(10)
)

INSERT INTO @values(Value) VALUES ('1')
INSERT INTO @values(Value) VALUES ('2')
INSERT INTO @values(Value) VALUES ('3')
INSERT INTO @values(Value) VALUES ('4')
INSERT INTO @values(Value) VALUES ('5')
INSERT INTO @values(Value) VALUES ('Many')
INSERT INTO @values(Value) VALUES ('Many')
INSERT INTO @values(Value) VALUES ('Many')
INSERT INTO @values(Value) VALUES ('Many')
INSERT INTO @values(Value) VALUES ('Many')

DECLARE @rowCount int
SET @rowCount = 100000

WHILE(@rowCount > 0)
BEGIN
    DECLARE @valueIndex int
    SET @valueIndex = CAST(RAND() * 10 + 1 as int)
    DECLARE @selectedValue nvarchar(10)
    SELECT @selectedValue = Value FROM @values WHERE Id = @valueIndex
    DECLARE @isActive bit
    SELECT @isActive = CASE 
            WHEN RAND() < 0.001 THEN 1 
            ELSE 0
           END
    INSERT INTO IndexTest(Active, IndexedValue) VALUES (@isActive, @selectedValue)
    SET @rowCount = @rowCount - 1
END

SELECT count(*) FROM IndexTest WHERE Active = 1
SELECT count(*) FROM IndexTest WHERE Active = 0

SELECT count(*) FROM IndexTest WHERE IndexedValue = '1'
SELECT count(*) FROM IndexTest WHERE IndexedValue = 'Many'

在我看来它总是使用此查询计划中的索引:

query plan

答案 1 :(得分:1)

它会创建一个直方图,然后使用它。

使用位列,可以很好地了解有多少是0和1

对于一个字符串列,它会大致了解“band”(值a,b,c等)。数字相同(它创建x范围的值范围)。

只需查看统计信息在管理工作室中的外观 - 您实际上可以访问直方图。

答案 2 :(得分:1)

您只需查看统计信息并亲眼看看:) DBCC SHOW_STATISTICS。请参阅备注部分,它对如何实际存储和使用直方图有一个很好的解释:

  

创建直方图,查询   优化器对列值进行排序,   计算值的数量   匹配每个不同的列值和   然后将列值聚合到   最多200个连续直方图   脚步。每一步都包括一系列   列值后跟上部   绑定列值。范围包括   所有可能的列值之间   边界值,不包括   边界值本身。最低的   已排序的列值是   第一个上限值   直方图步骤。

alt text

  

对于每个直方图步骤:

     
      
  • 粗线表示上边界值(RANGE_HI_KEY)和   它发生的次数(EQ_ROWS)
  •   
  • RANGE_HI_KEY左侧的实线区域表示列值的范围   和每个的平均次数   发生列值(AVG_RANGE_ROWS)。   第一个AVG_RANGE_ROWS   直方图步长始终为0.
  •   
  • 虚线表示用于估算总数的采样值   范围内的不同值的数量   (DISTINCT_RANGE_ROWS)和总数   范围内的值(RANGE_ROWS)。   查询优化器使用RANGE_ROWS   和DISTINCT_RANGE_ROWS来计算   AVG_RANGE_ROWS并且不存储   采样值。
  •   
     

查询优化器定义了   根据他们的直方图步骤   统计学意义。它使用了   最大差分算法   最小化步骤数   直方图,同时最大化   边界之间的差异   值。最大步数是   200.直方图步骤的数量可以少于不同的数量   值,即使是较少的列   超过200个边界点。例如,   具有100个不同值的列可以   有一个小于100的直方图   边界点。