SQLServer 表的索引碎片查询和处理

目录
  • 1.查看索引的碎片率
  • 2.reorganize索引
  • 3.rebuild索引
  • 4.rebuild表上所有的索引
  • 5.rebuild数据库中所有的索引  

1.查看索引的碎片率

SELECT object_name(ips.object_id) AS TableName, ips.index_id, name AS IndexName,
avg_fragmentation_in_percent,db_name(ips.database_id) AS DatabaseName
FROM sys.dm_db_index_physical_stats
    (Db_id(DB_NAME())
        , NULL
        , NULL
        , NULL
        , NULL) AS ips
INNER JOIN sys.indexes AS SI ON ips.object_id = SI.object_id AND ips.index_id = SI.index_id
WHERE ips.avg_fragmentation_in_percent > 5 AND SI.index_id <> 0

索引的碎片率低于5%或者,索引的页数少于1000,可以忽略;
索引碎片率在5%-30%之间的,建议reorganize;
索引碎片率大于30%的,建议rebuild。

2.reorganize索引

alter index [索引名] on [dbo].[表名] reorganize;

3.rebuild索引

alter index [索引名] on [dbo].[表名] rebuild;

4.rebuild表上所有的索引

alter index all on [dbo].[表名] rebuild;

5.rebuild数据库中所有的索引  

USE [数据库名]
GO
DECLARE @NoOfPartitions BIGINT;
DECLARE @objectid INT;
DECLARE @indexid INT;
DECLARE @idxname NVARCHAR(255);
DECLARE @objname NVARCHAR(255);
DECLARE @partitionnum BIGINT;
DECLARE @schemaname NVARCHAR(255);
DECLARE @partitions BIGINT;
DECLARE @frag FLOAT;
DECLARE @statement VARCHAR(8000);
-- checking existance of the table that we create for temporary purpose
IF OBJECT_ID('defrag_work', 'U') IS NOT NULL
  DROP TABLE defrag_work;
-- Copy the fragmented indexes data into defrag_work table
-- All the indexes that has fragmentation < 5 are getting stored into our work table
SELECT  [object_id] AS objectid ,
        index_id AS indexid ,
        partition_number AS partition_no ,
        avg_fragmentation_in_percent AS frag
INTO    defrag_work
FROM    sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED')
WHERE   avg_fragmentation_in_percent >5.0 and index_id > 0;
-- cursor to process the list of partitions
DECLARE partitions CURSOR
FOR
    SELECT  *
    FROM    defrag_work;
-- Open the cursor.
OPEN partitions;
-- Looping through the partitions
FETCH NEXT
   FROM partitions
   INTO @objectid, @indexid, @partitionnum, @frag;
WHILE @@FETCH_STATUS = 0
    BEGIN;
        SELECT  @objname= QUOTENAME(so.name) ,
                @schemaname = QUOTENAME(ss.name)
        FROM    sys.objects AS so
                JOIN sys.schemas AS ss ON ss.schema_id = so.schema_id
        WHERE   so.object_id = @objectid;
        SELECT  @idxname = QUOTENAME(name)
        FROM    sys.indexes
        WHERE   object_id = @objectid
                AND index_id = @indexid;
        SELECT  @NoOfPartitions = COUNT(*)
        FROM    sys.partitions
        WHERE   object_id = @objectid
                AND index_id = @indexid;
/*
Let's say N = fragmentation percentage
N <= 5 = IGNORE
5 < N < 30 = REORGANIZE
N > 30 = REBUILD
*/
        IF (@frag < 30.0) -- @frag > 5 is already filtered in our first query, so we need that condition here
            BEGIN;
                SELECT  @statement = 'ALTER INDEX ' + @idxname + ' ON '
                        + @schemaname + '.' + @objname + ' REORGANIZE';
                IF @NoOfPartitions > 1
                    SELECT  @statement = @statement + ' PARTITION='
                            + CONVERT (CHAR, @partitionnum);
                EXEC (@statement);
            END;
        IF @frag >= 30.0
            BEGIN;
                SELECT  @statement = 'ALTER INDEX ' + @idxname + ' ON '
                        + @schemaname + '.' + @objname + ' REBUILD';
                IF @NoOfPartitions > 1
                    SELECT  @statement = @statement + ' PARTITION='
                            + CONVERT (CHAR, @partitionnum);
                EXEC (@statement);
            END;
        PRINT 'Executed ' + @statement;
        FETCH NEXT FROM partitions INTO @objectid, @indexid, @partitionnum,
            @frag;
    END;
-- Close and deallocate the cursor.
CLOSE partitions;
DEALLOCATE partitions;
-- drop the table
IF OBJECT_ID('defrag_work', 'U') IS NOT NULL
  DROP TABLE defrag_work;

到此这篇关于SQLServer 表的索引碎片查询和处理的文章就介绍到这了,更多相关SQLServer 表索引碎片内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • sqlserver2005自动创建数据表和自动添加某个字段索引

    创建数据表的SQL语句如下: string tatlename = "T_useruid";//定义一个变量.用于自动创建数据表的名称,当前表名为:T_useruid string sql = "CREATE TABLE [dbo].[" + tatlename + "]([Cid] [int] IDENTITY(1,1) NOT NULL,[Uid] [nchar](32) COLLATE Chinese_PRC_CI_AS NULL,CONSTRAIN

  • 详解sqlserver查询表索引

    SELECT   索引名称=a.name ,表名=c.name ,索引字段名=d.name ,索引字段位置=d.colid FROM sysindexes a JOIN sysindexkeys b ON a.id=b.id AND a.indid=b.indid JOIN sysobjects c ON b.id=c.id JOIN syscolumns d ON b.id=d.id AND b.colid=d.colid WHERE a.indid NOT IN(0,255) -- and

  • 为什么Mysql 数据库表中有索引还是查询慢

    目录 前言: 1.字段类型不匹配导致的索引失效 2.被索引字段使用了表达式计算 3.被索引字段使用了内置函数 4.like 使用了 %X 模糊匹配 5.索引字段不是联合索引字段的最左字段 6.or 分割的条件 7.in.not in 可能会导致索引失效 总结 前言: 问题分析: 在进行数据库查询的时候,我们都知道索引可以加快数据查询的效率.但是在实际的业务场景下,经常会遇到即使在表中增加了索引,但是同样还是会出现数据查询慢的问题.这就需要具体分析数据查询慢的具体原因到底是什么了. 首先需要进行确

  • SqlServer 表单查询问题及解决方法

    Q1:表StudentScores如下,用一条SQL语句查询出每门课都大于80分的学生姓名 Q2:表DEMO_DELTE如下,删除除了自动编号不同,其他都相同的学生冗余信息 Q3:Team表如下,甲乙丙丁为四个球队,现在四个球对进行比赛,用一条sql语句显示所有可能的比赛组合 Q4:请考虑如下SQL语句在Microsoft SQL Server 引擎中的逻辑处理顺序 USE TSQLFundamentals2008 SELECT empid,YEAR(orderdate) AS orderyea

  • 提升SQL Server速度 整理索引碎片

    凭经验,这是索引碎片问题.检查索引碎片DBCC SHOWCONTIG(表),得到如下结果: DBCC SHOWCONTIG 正在扫描 'A' 表... 表: 'A'(884198200):索引 ID: 1,数据库 ID: 13 已执行 TABLE 级别的扫描. - 扫描页数.....................................: 3127 - 扫描扩展盘区数...............................: 403 - 扩展盘区开关数..............

  • postgresql通过索引优化查询速度操作

    当数据量比较大的时候,提升查询效率就是需要去考虑的事情了.一个百万级别的表格,如果不做任何优化的话,即使是最简单的查询语句执行起来也是慢的让人难以接受:当然"优化"本身是一个比较复杂的工程,从设计表.字段到查询语句的写法都有很多讲究,这里只考虑索引的方式,且是最普通的索引: 下面的操作中对应数据库表w008_execrise_info(8000数据量), w008_wf02_info(4000数据量) 1 任务表数据 SELECT w.* FROM w008_wf02_info w W

  • Oracle 9i轻松取得建表和索引的DDL语句

    正在看的ORACLE教程是:Oracle 9i轻松取得建表和索引的DDL语句.我们都知道在9i之前,要想获得建表和索引的语句是一件很麻烦的事.我们通常的做法都是通过export with rows=no来得到,但它的输出因为格式的问题并不能直接拿来用.而另一种方法就是写复杂的脚本来查询数据字典,但这对于一稍微复杂的对象,如IOT和嵌套表等,还是无法查到. 从数据字典中获得DDL语句是经常要用的,特别是在系统升级/重建的时候.在Oracle 9i中,我们可以直接通过执行dbms_metadata从

  • Oracle9i取得建表和索引的DDL语句

    正在看的ORACLE教程是:Oracle9i取得建表和索引的DDL语句.我们都知道在9i之前,要想获得建表和索引的语句是一件很麻烦的事.我们通常的做法都是通过export with rows=no来得到,但它的输出因为格式的问题并不能直接拿来用.而另一种方法就是写复杂的脚本来查询数据字典,但这对于一稍微复杂的对象,如IOT和嵌套表等,还是无法查到. 从数据字典中获得DDL语句是经常要用的,特别是在系统升级/重建的时候.在Oracle 9i中,我们可以直接通过执行dbms_metadata从数据字

  • SQLSERVER中忽略索引提示

    当我们想让某条查询语句利用某个索引的时候,我们一般会在查询语句里加索引提示,就像这样 复制代码 代码如下: SELECT id,name from TB with (index(IX_xttrace_bal)) where bal<100 当在生产环境里面,由于这个索引提示的原因,优化器一般不会再去考虑其他的索引,那有时候这个索引提示可能会导致查询变慢 经过你的测试,发现确实是因为这个索引提示的关系导致查询变慢,但是SQL服务器已经缓存了这条SQL语句的执行计划,如果修改SQL语句的话可能会有影

  • 如何使用索引提高查询速度

    使用索引提高查询速度1.前言在web开发中,页面模板,业务逻辑(包括缓存.连接池)和数据库这三个部分,数据库在其中负责执行SQL查询并返回查询结果,是影响网站速度最重要的性能瓶颈.本文主要针对MySql数据库,双十一的电商大战,引发了淘宝技术热议,而淘宝现在去IOE(I代表IBM的缩写,即去IBM的存储设备和小型机;O是代表Oracle的缩写,也即去Oracle数据库,采用MySQL和Hadoop替代的解决方案,;E是代表EMC2,即去EMC2的设备性,用PC Server替代EMC2),大量采

  • Oracle轻松取得建表和索引的DDL语句

    我们都知道在9i之前,要想获得建表和索引的语句是一件很麻烦的事.我们可以通过export with rows=no来得到,但它的输出因为格式的问题并不能直接拿来用.而另一种方法就是写复杂的脚本来查询数据字典,但这对于一稍微复杂的对象,如IOT和嵌套表等,还是无法查到. 从数据字典中获得DDL语句是经常要用的,特别是在系统升级/重建的时候.在Oracle 9i中,我们可以直接通过执行dbms_metadata从数据字典中查处DDL语句.使用这个功能强大的工具,我们可以获得单个对象或整个SCHEMA

  • Lucene实现索引和查询的实例讲解

    0引言 随着万维网的发展和大数据时代的到来,每天都有大量的数字化信息在生产.存储.传递和转化,如何从大量的信息中以一定的方式找到满足自己需求的信息,使之有序化并加以利用成为一大难题.全文检索技术是现如今最普遍的信息查询应用,生活中利用搜索引擎,在博客论坛中查找信息,这些搜索的核心原理就是本文要实现的全文检索技术.随着文档信息数字化的实现,将信息有效存储并及时准确的提取是每一个公司.企业和单位要做好的基础.针对英文的全文检索已经有很多成熟的理论和方法,开放源代码的全文检索引擎Lucene 是Apa

随机推荐

其他