本文章转载:http://database.51cto.com/art/201108/282408.htm

SQL Server数据库中,当索引碎片太多时,就会拖慢数据库查询的速度。这时我们可以通过整理索引碎片和重建索引来解决,本文我们主要就介绍了这部分内容,希望能够对您有所帮助。

 

SQL Server数据库操作中,当数据库中的记录比较多的时候,我们可以通过索引来实现查询。但是当索引碎片太多的时候,就会很严重地影响到查询的速度。这时候我们可以采取两种方法来解决:一种时整理索引碎片,另一种是重建索引

索引是数据库引擎中针对表(有时候也针对视图)建立的特别数据结构,用来帮助查找和整理数据。索引的重要性体现在能够使数据库引擎快速返回查询
结果。当对索引所在的基础数据表进行修改时(包括插入、删除和更新等操作),会导致索引碎片的产生。当索引的逻辑排序和基础表或视图的物理排序不匹配时,
就会产生索引碎片。随着索引碎片的不断增多,查询响应时间就会变慢,查询性能也会下降。在SQL Server
2005中,要解决这个问题,要么重新组织索引要么重新生成索引。

索引碎片的产生:http://blog.sina.com.cn/s/blog_792e033201013fkj.html

索引能够加快对表的访问速度,然而任何事物都有两面性,索引在带给我们便利的同时也会占用额外的磁盘空间,并且我们在对表进行增删改的操作时也要消耗额外的时间来更新索引。而在我们对包含索引的表进行增删改时,也会造成索引碎片,久而久之,索引碎片程度越来越高,反而会降低我们对表的访问速度。因此作为数据库管理员,要定期维护索引,修复索引碎片。

怎样确定索引是否有碎片? http://blog.tianya.cn/blogger/post_read.asp?BlogID=2587659&PostID=24488142
  
  SQLServer提供了一个数据库命令――DBCC SHOWCONTIG――来确定一个指定的表或索引是否有碎片。
  DBCC SHOWCONTIG
  数据库平台命令,用来显示指定的表的数据和索引的碎片信息。
  
  DBCC SHOWCONTIG 权限默认授予 sysadmin固定服务器角色或 db_owner 和 db_ddladmin固定数据库角色的成员以及表的所有者且不可转让。
  语法(SQLServer2000)
  
  DBCC SHOWCONTIG
  [ ( { table_name | table_id| view_name | view_id }
  [ , index_name | index_id ]
  )
  ]
  [ WITH { ALL_INDEXES
  | FAST [ , ALL_INDEXES ]
  | TABLERESULTS [ , { ALL_INDEXES } ]
  [ , { FAST | ALL_LEVELS } ]
  }
  ]
  
  语法(SQLServer7.0)
  
  DBCC SHOWCONTIG
  [ ( table_id [,index_id ]
  )
  ]

 

那么SQL Server如何的定期清理索引碎片呢?可以做个Job作业计划,定期的执行。

--更新统计信息
EXEC sp_updatestats ---索引优化
DECLARE @tableName NVARCHAR(50) ,
@indexName NVARCHAR(50) ,
@fragmentPercent NVARCHAR(20) ,
@sql NVARCHAR(200)= ''
DECLARE indexFragment_cursor CURSOR
FOR
SELECT o.name AS tableName ,
ix.name AS indexName ,
avg_fragmentation_in_percent AS fragmentPercent--,
--dip.fragment_count,
--dip.avg_fragment_size_in_pages
FROM sys.dm_db_index_physical_stats(DB_ID() ,NULL ,NULL ,NULL ,NULL) dip
INNER JOIN sys.indexes ix ON ix.index_id = dip.index_id
AND ix.object_id = dip.object_id
INNER JOIN sys.objects o ON ix.object_id = o.object_id
WHERE dip.index_id > 0
AND avg_fragmentation_in_percent > 5
ORDER BY avg_fragmentation_in_percent DESC --打开游标
OPEN indexFragment_cursor
FETCH NEXT
FROM indexFragment_cursor
INTO @tableName ,@indexName ,@fragmentPercent
WHILE @@FETCH_STATUS = 0
BEGIN
--print @tableName+'----'+@indexName++'----'+@fragmentPercent
SET @sql = 'ALTER INDEX ' + QUOTENAME(@indexName) + ' on '
+ QUOTENAME(@tableName)
+ CASE WHEN @fragmentPercent <= '30' THEN ' REORGANIZE;'
WHEN @fragmentPercent > '30' THEN ' REBUILD;'
END
--print @sql
EXEC(@sql)
--移到下一行记录
FETCH NEXT
FROM indexFragment_cursor
INTO @tableName ,@indexName ,@fragmentPercent
END --关闭,释放游标
CLOSE indexFragment_cursor
DEALLOCATE indexFragment_cursor GO

  SQL 2008 R2索引的重建:http://www.2cto.com/database/201204/128616.html

项目升级数据库由SQL2000升级到2008R2,今天对数据库表进行碎片扫描,发现有些表碎片较大,于是决定重建索引,联机帮助是最好的老师,将相关脚本摘录备后查。

参考sys.dm_db_index_physical_stats

检查索引碎片情况

SELECT

    OBJECT_NAME(object_id) as objectname,

    object_id AS objectid,  www.2cto.com  

    index_id AS indexid,

    partition_number AS partitionnum,

    avg_fragmentation_in_percent AS fra

FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED')

WHERE avg_fragmentation_in_percent > 10.0 AND index_id > 0;

使用脚本中的 sys.dm_db_index_physical_stats 重新生成或重新组织索引 (来源于联机帮助)

SET NOCOUNT ON;

DECLARE @objectid int;

DECLARE @indexid int;

DECLARE @partitioncount bigint;

DECLARE @schemaname nvarchar(130); 

DECLARE @objectname nvarchar(130); 

DECLARE @indexname nvarchar(130); 

DECLARE @partitionnum bigint;

DECLARE @partitions bigint;

DECLARE @frag float;  www.2cto.com  

DECLARE @command nvarchar(4000); 

-- Conditionally select tables and indexes from the sys.dm_db_index_physical_stats function 

-- and convert object and index IDs to names.

SELECT

    object_id AS objectid,

    index_id AS indexid,

    partition_number AS partitionnum,

    avg_fragmentation_in_percent AS frag

INTO #work_to_do

FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED')

WHERE avg_fragmentation_in_percent > 10.0 AND index_id > 0;

-- Declare the cursor for the list of partitions to be processed.

DECLARE partitions CURSOR FOR SELECT * FROM #work_to_do;

-- Open the cursor.

OPEN partitions;

-- Loop through the partitions.

WHILE (1=1)

    BEGIN;

        FETCH NEXT

           FROM partitions

           INTO @objectid, @indexid, @partitionnum, @frag;

        IF @@FETCH_STATUS < 0 BREAK;

        SELECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name)

        FROM sys.objects AS o  

        JOIN sys.schemas as s ON s.schema_id = o.schema_id

        WHERE o.object_id = @objectid;

        SELECT @indexname = QUOTENAME(name)

        FROM sys.indexes

        WHERE  object_id = @objectid AND index_id = @indexid;

        SELECT @partitioncount = count (*)

        FROM sys.partitions

        WHERE object_id = @objectid AND index_id = @indexid;

-- 30 is an arbitrary decision point at which to switch between reorganizing and rebuilding.

        IF @frag < 30.0

            SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';

        IF @frag >= 30.0

            SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';

        IF @partitioncount > 1

            SET @command = @command + N' PARTITION=' + CAST(@partitionnum AS nvarchar(10));  www.2cto.com  

        EXEC (@command);

        PRINT N'Executed: ' + @command;

    END;

-- Close and deallocate the cursor.

CLOSE partitions;

DEALLOCATE partitions;

-- Drop the temporary table.

DROP TABLE #work_to_do;

GO

  

 UPDATE STATISTICS更新统计信息来提高查询效率. 

该命令在一张表或者索引了的视图上更新查询优化统计数字信息. 默认情况下, 查询优化器已经更新了必要的用来提高查询计划的统计信息; 在某些情况下, 你可以通过使用UPDATE STATISTICS 命令或者存储过程sp_updatestats 来比默认更频繁地更新统计信息来提高查询效率.

更新统计信息能确保查询能以最新的统计信息来编译. 然而, 更新统计信息会引起查询的重新编译. 我们建议不要过于频繁地更新统计信息, 因为这里有一个在提高查询计划和用来重新编译查询的权衡. 具体的权衡要看你的应用程序而定.

SQL Server通过整理索引碎片和重建索引提高速度的更多相关文章

  1. [笔记整理]SQL Server 索引碎片 和 重建索引

    铺垫知识点: 数据库存储本身是无序的,建立了聚集索引,会按照聚集索引物理顺序存入硬盘.既键值的逻辑顺序决定了表中相应行的物理顺序 多数情况下,数据库读取频率远高于写入频率,索引的存在 为了读取速度牺牲 ...

  2. SQL Server调优系列基础篇(索引运算总结)

    前言 上几篇文章我们介绍了如何查看查询计划.常用运算符的介绍.并行运算的方式,有兴趣的可以点击查看. 本篇将分析在SQL Server中,如何利用先有索引项进行查询性能优化,通过了解这些索引项的应用方 ...

  3. SQL Server 2016新特性:列存储索引新特性

    SQL Server 2016新特性:列存储索引新特性 行存储表可以有一个可更新的列存储索引,之前非聚集的列存储索引是只读的. 非聚集的列存储索引支持筛选条件. 在内存优化表中可以有一个列存储索引,可 ...

  4. (转)Sql Server之旅——第八站 复合索引和include索引到底有多大区别?

    索引和锁,这两个主题对我们开发工程师来说,非常的重要...只有理解了这两个主题,我们才能写出高质量的sql语句,在之前的博客中,我所说的 索引都是单列索引...当然数据库不可能只认单列索引,还有我这篇 ...

  5. SQL Server调优系列进阶篇 - 如何索引调优

    前言 上一篇我们分析了数据库中的统计信息的作用,我们已经了解了数据库如何通过统计信息来掌控数据库中各个表的内容分布.不清楚的童鞋可以点击参考. 作为调优系列的文章,数据库的索引肯定是不能少的了,所以本 ...

  6. SQL Server 调优系列进阶篇 - 如何索引调优

    前言 上一篇我们分析了数据库中的统计信息的作用,我们已经了解了数据库如何通过统计信息来掌控数据库中各个表的内容分布.不清楚的童鞋可以点击参考. 作为调优系列的文章,数据库的索引肯定是不能少的了,所以本 ...

  7. SQL Server 语句整理

    1. 创建数据库 create database dbName 2. 删除数据库 drop database dbName 3. 备份sql server --- 创建 备份数据的 device US ...

  8. 【SQL Server】系统学习之二:索引优化

    页大小8192个字节,行限制为8060字节(大型对象除外). 包含varchar nvarchar varbinary sql_variant(8012,object类型) clr 的行,如果行大小超 ...

  9. Sql Server查询性能优化之走出索引的误区

    据了解绝大多数开发人员对于索引的理解都是一知半解,局限于大多数日常工作没有机会.也什么没有必要去关心.了解索引,实在哪天某个查询太慢了找到查询条件建个索引就ok,哪天又有个查询慢了,再建立个索引就是, ...

随机推荐

  1. Struts2中的链接标签 <s:url>和<s:a>---在action中获取jsp表单提交的参数(转)

    转自:http://sgl124764903.iteye.com/blog/444183 1.普通链接 Web程序中最普通的应用是链接到其他页面,下面看Welcome.jsp. <%@ page ...

  2. Linux内存点滴:用户进程内存空间

    原文出处:PerfGeeks 经常使用top命令了解进程信息,其中包括内存方面的信息.命令top帮助文档是这么解释各个字段的.VIRT , Virtual Image (kb)RES, Residen ...

  3. dedecms模版制作活动的折叠菜单

    需要做成这种样式 url请求为这样: http://m03.com/plus/list.php?tid=19 这些菜单项都有对应的tid项,页面刷新后,应该将所有的菜单折叠起来,对于tid=19的菜单 ...

  4. Wdcp缺少mod_rewite模块

    1.下载apache源码包,解压并查找到mod_rewrite.c文件 tar -zxvf httpd-2.2.27.tar.gz cd httpd-2.2.27 [root@localhost ht ...

  5. WAMP学习日记之:Apache发布php网站

    1.修改httpd.conf 文件,以便让Apache和php模块建立关联 2.配置php.ini文件 修改httpd.conf 文件,以便让Apache和php模块建立关联 如何让apache和ph ...

  6. CSS远程加载字体

    CSS 远程加载字体的方法,做网站CSS的都知道,用户浏览网站时,网页上的字体是加载本地的.换言之,如果网站使用了用户电脑所没有安装的字体,那显示字体就会被默认字体所代替了,自然效果就大受影响了. 上 ...

  7. HDU 1995

    Problem Description 用1,2,...,n表示n个盘子,称为1号盘,2号盘,....号数大盘子就大.经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故. ...

  8. 使用OpenSSL API进行安全编程

    http://www.ibm.com/developerworks/cn/linux/l-openssl.html OpenSSL API 的文档有些含糊不清.因为还没有多少关于 OpenSSL 使用 ...

  9. centos jdk切换

        #这里找下载路径 http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html    ...

  10. SQL SERVER 2008 nvarchar 转换 deciaml 失败(nvarchar to decimal)

    转换数据发生 消息 8115,级别 16,状态 6,第 1 行 将 nvarchar 转换为数据类型 numeric 时出现算术溢出错误. nvarchar 是带很长小数,直接转换成decimal 失 ...