技术开发 频道

加速SQL Server 2005中的表计数性能

  【IT168 专稿】当我们希望获得一个表中符合条件的记录的行数时,一般借助于T-SQL函数count(*)来实现。不过,如果你的表中包含了数百万条记录,返回整个表的记录数可能需要花费较长时间,会导致查询性能非常低。

  1.Count()函数

  DBA们都知道如何使用count(*)函数,也知道它对性能的影响。SQL Server需要进行一次完整的索引/表扫描,才能返回表的记录总数。建议DBA不要针对这个表使用聚合函数count(),因为它会影响数据库的性能。接下来我们在示例数据库AdventureWorkstation的查询分析器中执行以下查询语句:

use AdventureWorks
go
select count (*) from Sales.SalesOrderDetail

  查询分析器返回的结果为121317行。

  当我们点击SQL Server 2005 Management Studio工具栏中的“显示预计的执行计划”图标时,我们可以看到如下图示:


图1 查看count(*)执行计划

  如上图所示,该函数执行过程中将从右至左执行如下操作:

  •对整个表进行索引扫描,这是一个相当耗时的过程。
  •接下来执行流聚合。

  2.新方法row_count()

  在SQL Server 2005的对象目录视图(Object Catalog Views)包含如下信息:sys.partitions和sys.allocation_units被用来获得整个表的记录总数。这个函数可以在SQL Server 2005中使用。

  sys.partitions视图
  sys.partitions视图包含了数据库中所有表和索引的每个分区在表中对应的每一行。即使SQL Server 2005中的所有表和索引并未显式分区,也至少在这个视图中包含一个分区。

  该视图包含如下字段,它们将被用于这个新方法:

字段名称
数据类型
描述
partition_id
bigint
分区的ID,它在一个数据库中是唯一的。
object_id
int
分区所属表的ID。每个表至少包含一个分区。
index_id
int
分区所属对象内索引的ID。
0:heap表
1:具有集群索引
rows
bigint
分区中表的行数。

  sys.allocation_units
视图
  sys.allocation_units视图包含了数据库中的每个分配单元在表中的每一行。 

  该视图中可以被新方法使用的字段如下:

字段名称
数据类型
描述
container_id
bigint
container_id=sys.partitions.partition_id
Type
tinyint
0 = 已删除
1 = 行内数据(除LOB之外的所有数据类型)
2 = 大型对象(LOB)数据(text、ntext、 image、xml)
3 = 行溢出数据

  在这个新用户自定义函数row_count中,[sys.partitions]视图与[sys.allocation_units]视图是相关联的。过滤器的选择基于如下标准:

  ·[sys.allocation_units].type=1,只获得行数据,不包含诸如text、ntext、image等类型的大型对象。
  ·[sys.partitions].index_id为0表示是heap表,为1表示是集群表。
  ·[sys.partitions].rows不为空。
 
  用户自定义函数row_count在每一个数据库中被执行,因此其权限为public。
0
相关文章