好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

第十二章SQLServer统计信息(2)非索引键上统计信息的影

前言: 索引 对性能方面总是扮演着一个重要的角色,实际上,查询优化器首先检查谓词上的 统计 信息 ,然后才决定用什么 索引 。一般情况下,默认会在创建 索引 时, 索引 列上均创建 统计 信息 。但是不代表在非 索引 键上的 统计 信息 对性能没有用。 如果

前言:

索引 对性能方面总是扮演着一个重要的角色,实际上,查询优化器首先检查谓词上的 统计 信息 ,然后才决定用什么 索引 。一般情况下,默认会在创建 索引 时, 索引 列上均创建 统计 信息 。但是不代表在非 索引 键上的 统计 信息 对性能没有用。

如果表上的所有列都有 索引 ,那么将会是数据库负担不起,同时也不是一个好想法,包括谓词中用到的所有列加 索引 同样也不是好方法。因为 索引 会带来负载。因为需要空间存放 索引 ,且每个 DML 语句都会需要更新 索引 。

一般来说,建议在 where 或者 ON 子句中出现的列上添加 索引 ,但是由于某些情况,很难在所有的谓词上都创建 索引 ,此时创建 统计 信息 会是一个最起码的改进。如果 Auto_Create_Statistics 为 ON ,那么优化器会帮你做这一步。

准备工作:

默认情况下, Auto_Create_Statistics 在数据库级别是设为 ON 的,但是为了下面需要这里先改成 OFF :

ALTER DATABASE AdventureWorks2012 SET AUTO_CREATE_STATISTICS OFF
GO
ALTER DATABASE AdventureWorks2012 SET AUTO_UPDATE_STATISTICS OFF
GO
 


然后创建一个新表用于本文使用:

SELECT  *
INTO    SalesOrdDemo
FROM    Sales.SalesOrderHeader
GO
 


步骤:

1、 对于新表,现在是没有 统计 信息 在上面的,可以使下面语句来验证:

SELECT  object_id ,
        OBJECT_NAME(object_id) AS TableName ,
        name AS StatisticsName ,
        auto_created
FROM    sys.stats
WHERE   object_id = OBJECT_ID('SalesOrdDemo')
ORDER BY object_id DESC 
GO
 


因为没有 统计 信息 ,所以这个查询是没有数据的。

2、 现在在新表上创建一个聚集 索引 :

 CREATE CLUSTERED INDEX idx_SalesOrdDemo_SalesOrderID ON SalesOrdDemo(SalesOrderID)
GO
 


3、 再次运行步骤一的脚本,可以看到已经有了数据,现在来执行下面的语句,并开启执行计划:

SELECT  s.salesorderid ,
        so.SalesOrderDetailID
FROM    salesordDemo AS s
        INNER JOIN Sales.SalesOrderDetail AS so ON s.salesorderid = so.SalesOrderID
WHERE   s.duedate = '2005-09-19 0.000'
 


4、 下面截图是步骤 3 中的执行计划,关注一下 SalesOrdDemo 表上有聚集 索引 扫描,这是合理的,因为没有 WHERE 子句在使用 SalesOrderID 列。而 SalesOrderDetails 表有非聚集 索引 扫描。还可以看到实际行数和估计行数有很大差异。

5、 现在是时候在新表的 DueDate 上创建 统计 信息 ,因为在查询中这个列并不包含在 索引 里面。

CREATE STATISTICS st_SaledOrdDemo_DueDate ON SalesOrdDemo(DueDate)
GO
 


6、 再次执行步骤 3 的脚本,不需要任何改动:

SELECT  s.salesorderid ,
        so.SalesOrderDetailID
FROM    salesordDemo AS s
        INNER JOIN Sales.SalesOrderDetail AS so ON s.salesorderid = so.SalesOrderID
WHERE   s.duedate = '2005-09-19 0.000'
 


7、 对比上面的执行计划,此时在 SalesOrderDetails 表上已经从非聚集 索引 扫描变成了聚集 索引 查找,且开销只有 2% ,更总要的是实际行数和预估行数相差无几:

分析:

如果优化器可以获得谓词上列的 统计 信息 ,那么相会知道将要返回的行数,并且帮助优化器选择最佳的执行方式。

查看更多关于第十二章SQLServer统计信息(2)非索引键上统计信息的影的详细内容...

  阅读:24次