我们知道,合理的索引能大幅提升性能,但冗余的索引也会降低数据库性能。随着我们业务的发展,数据库的中的表、表结构、查询的内容都有可能发生变化。这样,有的索引就可能不再使用了,需要删除(因为维护索引即浪费存储,又耗费性能);而有的表则需要修改或者增加索引。本文主要给出快速确定不再使用的索引的查找方式之一,动态视图(DMV)查询。

无用索引
首先我们来看一下如何查询无用的索引。sys.dm_db_index_usage_stats 记录自上次重启或数据库离线或重置统计信息后使用到的索引,sys.indexes 记录数据中所有表的索引,排除掉最近使用的索引,即为最近没有使用的索引,具体脚本如下:

--查询数据库中没有使用过到索引
USE WideWorldImporters;
GO
DECLARE @dbid INT=DB_ID('WideWorldImporters');
WITH cte AS(
SELECT
[object_id],index_id
FROM sys.indexes
EXCEPT
SELECT
[object_id],index_id
FROM sys.dm_db_index_usage_stats
WHERE database_id=@dbid)
SELECT
o.name tableName,i.name indexName
FROM sys.indexes i
INNER JOIN cte ON cte.index_id=i.index_id AND cte.[object_id]=i.[object_id]
INNER JOIN sys.objects o ON i.[object_id]=o.[object_id]
WHERE o.[type] IN ('U','V') AND i.[type]>0;
因为我们只考察用户创建的表或者索引视图,最后我们只筛选出sys.objects 中type为“U”(用户创建的表)和“V”(用户创建的视图索引)。sys.indexes 中type=0是堆,所以也排除。下面给出产生删除索引的脚本:

DECLARE @dbid INT=DB_ID('WideWorldImporters');
WITH cte AS(
SELECT
[object_id],index_id
FROM sys.indexes
EXCEPT
SELECT
[object_id],index_id
FROM sys.dm_db_index_usage_stats
WHERE database_id=@dbid)
SELECT
--修改主键索引删除报错的问题
CASE WHEN is_primary_key=1 THEN 'ALTER TABLE '+ o.name +' DROP CONSTRAINT '+i.name
ELSE 'DROP INDEX '+i.name+' ON '+ o.name
END
FROM sys.indexes i
INNER JOIN cte ON cte.index_id=i.index_id AND cte.[object_id]=i.[object_id]
INNER JOIN sys.objects o ON i.[object_id]=o.[object_id]
WHERE o.[type] IN ('U','V') AND i.[type]>0;
上面的脚本每条对应一个表的一个索引的删除语句,当然也可以使用如下脚本产生一条语句。

DECLARE @dbid INT=DB_ID('WideWorldImporters');
DECLARE @sql VARCHAR(MAX);
WITH cte AS(
SELECT
[object_id],index_id
FROM sys.indexes
EXCEPT
SELECT
[object_id],index_id
FROM sys.dm_db_index_usage_stats
WHERE database_id=@dbid)
SELECT @sql=(
SELECT
--修改主键索引删除报错的问题
CASE WHEN is_primary_key=1 THEN 'ALTER TABLE '+ o.name +' DROP CONSTRAINT '+i.name
ELSE 'DROP INDEX '+i.name+' ON '+ o.name
END
FROM sys.indexes i
INNER JOIN cte ON cte.index_id=i.index_id AND cte.[object_id]=i.[object_id]
INNER JOIN sys.objects o ON i.[object_id]=o.[object_id]
WHERE o.[type] IN ('U','V') AND i.[type]>0
FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)');
--exec sp_executesql @sql
细心的读者会发现,上面最后一条语句(exec sp_executesql @sql)是注释掉的,直接这样执行是可以最快速的删除所有无用索引。但是,正如我们上面所说的,sys.dm_db_index_usage_stats 记录自上次重启或数据库离线或重置统计信息后使用到的索引,所以其记录的用到的索引可能是不全的(如果我们最近刚重启过数据库服务、数据库所在的服务器或者重置了动态视图),这样可能导致部分有用的索引也被删除掉,切记、切记、切记,生成的脚本不能直接执行。保险的做法是,至少,在数据库服务运行一个月做这样的事情,如果有经常重启维护的数据库服务,可以在数据库重启维护之前收集记录已经使用的索引。经过几个月或一年的记录,最终确定不需要的索引,再进行删除。

--查询某个表索引使用情况

SELECT TOP 100
obj.name AS 表名,
D.name AS 索引名称,
gs.user_scans+gs.user_seeks AS 使用次数
FROM sys.indexes D
INNER JOIN sys.dm_db_missing_index_groups G ON G.index_handle = D.index_id
INNER JOIN sys.dm_db_missing_index_group_stats GS ON G.index_group_handle = GS.group_handle
INNER JOIN sys.objects AS obj ON obj.object_id = D.object_id
AND obj.type = 'U'
WHERE obj.name = 'ReturnRefundDetails'

SQL Server 索引优化——无用索引的更多相关文章

  1. SQL SERVER全面优化-------索引有多重要?

    想了好久索引的重要性应该怎么写?讲原理结构?我估计大部分人不愿意看,也不愿意花那么多时间仔细研究.光写应用?感觉不明白原理一样不会用.举例说明?情况太多也写不全....到底该怎么写呢? 随便写吧,想到 ...

  2. mysql,sql server,oracle 唯一索引字段是否允许出现多个 null 值?

    最近一个项目,涉及到sql server 2008,因为业务需求,希望建立一个唯一索引,但是发现在sql server中,唯一索引字段不能出现多个null值,下面是报错信息: CREATE UNIQU ...

  3. Sql Server专题一:索引(中)

    写在前面的废话: 索引这个知识点,我前前后后不知道看了多少边,网上的文章五花八门,搞的我晕头转向,搞的牛逼点的就是测试索引带来的好处,还搞一大堆的测试数据出来,有意思吗?MS自己不会测试吗?这样的测试 ...

  4. SQL Server的非聚集索引中会存储NULL吗?

    原文:SQL Server的非聚集索引中会存储NULL吗? SQL Server的非聚集索引中会存储NULL吗? 这是个很有意思的问题,下面通过如下的代码,来说明,到底会不会存储NULL. --1.建 ...

  5. SQL Server强制使用特定索引 、并行度、锁

    SQL Server强制使用特定索引 .并行度 修改或删除数据前先备份,先备份,先备份(重要事情说三遍) 很多时候你或许为了测试.或许为了规避并发给你SQL带来的一些问题,常常需要强制指定目标sql选 ...

  6. 【SQL Server性能优化】运用SQL Server的全文检索来提高模糊匹配的效率

    原文:[SQL Server性能优化]运用SQL Server的全文检索来提高模糊匹配的效率 今天去面试,这个公司的业务需要模糊查询数据,之前他们通过mongodb来存储数据,但他们说会有丢数据的问题 ...

  7. SQL SERVER全面优化-------Expert for SQL Server 诊断系列

    现在很多用户被数据库的慢的问题所困扰,又苦于花钱请一个专业的DBA成本太高.软件维护人员对数据库的了解又不是那么深入,所以导致问题迟迟不能解决,或只能暂时解决不能得到根治.开发人员解决数据问题基本又是 ...

  8. SQL SERVER全面优化-------写出好语句是习惯

    前几篇文章已经从整体提供了诊断数据库的各个方面问题的基本思路...也许对你很有用,也许你觉得离自己太远.那么今天我们从语句的一些优化写法及一些简单优化方法做一个介绍.这对于很多开发人员来说还是很有用的 ...

  9. SQL SERVER全面优化

    今天我们从语句的一些优化写法及一些简单优化方法做一个介绍.这对于很多开发人员来说还是很有用的!为了方便阅读给出前文链接: SQL SERVER全面优化-------Expert for SQL Ser ...

随机推荐

  1. Theano入门笔记2:scan函数等

    1.Theano中的scan函数 目前先弱弱的认为:相当于symbolic的for循环吧,或者说计算图上的for循环,也可以用来替代repeat-until. 与scan相比,scan_checkpo ...

  2. (转)React事件处理函数必须使用bind(this)的原因

    1.JavaScript自身特性说明如果传递一个函数名给一个变量,之后通过函数名()的方式进行调用,在方法内部如果使用this则this的指向会丢失.示例代码:首先我们创建test对象并直接调用方法 ...

  3. Linux修改服务器Oracle字符集

    Linux安装Oracle时太仓促,没设置好,导入dmp字符集(ZHS16GBK)与服务器字符集(WE8MSWIN1252)对不上,导致导入数据失败: [oracle@ORACLE ~]$ sqlpl ...

  4. GoCN每日新闻(2019-10-03)

    GoCN每日新闻(2019-10-03) 国庆专辑:GopherChina祝大家国庆节快乐 GoCN每日新闻(2019-10-03) 1. 垃圾回收器如何监控你的应用程序 https://medium ...

  5. bluestart

    # Add nano as default editorexport EDITOR=nanoexport PULSE_LATENCY_MSEC=60 alias ls='ls --color=auto ...

  6. 理解Web路由(浅谈前后端路由与前后端渲染)

    1.什么是路由? 在Web开发过程中,经常会遇到『路由』的概念.那么,到底什么是路由?简单来说,路由就是URL到函数的映射. 路由的概念最开始是由后端提出来的,在以前用模板引擎开发页面的时候,是使用路 ...

  7. RedHat离线安装Python3以及各种依赖

    RedHat离线安装Python3以及各种依赖 1, yum install -y ncurses-libs zlib-devel mysql-devel bzip2-devel openssl-de ...

  8. eclipse没有server选项怎么解决

    eclipse没有server选项怎么解决 步骤: 1,在eclipse菜单“Help”中选择“InstallNew Software”如下图所示. 2,然后在Work with中点击Add,如下图所 ...

  9. null undefined NaN

    数据类型 6大基本 Number  String Boolean Undefined Null.  Symbol (ES6)   3大引用类型 object array Function Regexp ...

  10. spring cloud Eureka server 问题 Spring Cloud java.lang.TypeNotPresentException

    版本: spring-cloud.version : Greenwich.SR2 pom配置: <project xmlns="http://maven.apache.org/POM/ ...