SQL Server 索引优化——无用索引
我们知道,合理的索引能大幅提升性能,但冗余的索引也会降低数据库性能。随着我们业务的发展,数据库的中的表、表结构、查询的内容都有可能发生变化。这样,有的索引就可能不再使用了,需要删除(因为维护索引即浪费存储,又耗费性能);而有的表则需要修改或者增加索引。本文主要给出快速确定不再使用的索引的查找方式之一,动态视图(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 索引优化——无用索引的更多相关文章
- SQL SERVER全面优化-------索引有多重要?
想了好久索引的重要性应该怎么写?讲原理结构?我估计大部分人不愿意看,也不愿意花那么多时间仔细研究.光写应用?感觉不明白原理一样不会用.举例说明?情况太多也写不全....到底该怎么写呢? 随便写吧,想到 ...
- mysql,sql server,oracle 唯一索引字段是否允许出现多个 null 值?
最近一个项目,涉及到sql server 2008,因为业务需求,希望建立一个唯一索引,但是发现在sql server中,唯一索引字段不能出现多个null值,下面是报错信息: CREATE UNIQU ...
- Sql Server专题一:索引(中)
写在前面的废话: 索引这个知识点,我前前后后不知道看了多少边,网上的文章五花八门,搞的我晕头转向,搞的牛逼点的就是测试索引带来的好处,还搞一大堆的测试数据出来,有意思吗?MS自己不会测试吗?这样的测试 ...
- SQL Server的非聚集索引中会存储NULL吗?
原文:SQL Server的非聚集索引中会存储NULL吗? SQL Server的非聚集索引中会存储NULL吗? 这是个很有意思的问题,下面通过如下的代码,来说明,到底会不会存储NULL. --1.建 ...
- SQL Server强制使用特定索引 、并行度、锁
SQL Server强制使用特定索引 .并行度 修改或删除数据前先备份,先备份,先备份(重要事情说三遍) 很多时候你或许为了测试.或许为了规避并发给你SQL带来的一些问题,常常需要强制指定目标sql选 ...
- 【SQL Server性能优化】运用SQL Server的全文检索来提高模糊匹配的效率
原文:[SQL Server性能优化]运用SQL Server的全文检索来提高模糊匹配的效率 今天去面试,这个公司的业务需要模糊查询数据,之前他们通过mongodb来存储数据,但他们说会有丢数据的问题 ...
- SQL SERVER全面优化-------Expert for SQL Server 诊断系列
现在很多用户被数据库的慢的问题所困扰,又苦于花钱请一个专业的DBA成本太高.软件维护人员对数据库的了解又不是那么深入,所以导致问题迟迟不能解决,或只能暂时解决不能得到根治.开发人员解决数据问题基本又是 ...
- SQL SERVER全面优化-------写出好语句是习惯
前几篇文章已经从整体提供了诊断数据库的各个方面问题的基本思路...也许对你很有用,也许你觉得离自己太远.那么今天我们从语句的一些优化写法及一些简单优化方法做一个介绍.这对于很多开发人员来说还是很有用的 ...
- SQL SERVER全面优化
今天我们从语句的一些优化写法及一些简单优化方法做一个介绍.这对于很多开发人员来说还是很有用的!为了方便阅读给出前文链接: SQL SERVER全面优化-------Expert for SQL Ser ...
随机推荐
- 【03NOIP普及组】麦森数(信息学奥赛一本通 1925)(洛谷 1045)
[题目描述] 形如2P-1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果P是个素数,2P-1不一定也是素数.到1998年底,人们已找到了37个麦森数.最大的一个是P=3021377,它 ...
- (未完成)catalyst-system WriteUp(2019暑假CTF第一周reverse)
目录 预备学习--Linux实践:ELF文件格式分析 一.概述 二.分析ELF文件头(ELF header) 三.通过文件头找到section header table,理解其内容 四.通过secti ...
- 【大数据】分布式并行计算MapReduce
作业来源于:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3319 1. 用自己的话阐明Hadoop平台上HDFS和MapReduc ...
- Scala函数柯里化(Currying or Curry)
柯里化(Currying) 把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术. 简单的实现如下: scala> def ...
- 第10组 Beta冲刺(3/5)
链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 新增修改用户信息.任务完成反馈等功能API 服务器后端部署,API接口的bet ...
- 【软工实践】Beta版本演示
团队信息 队名:女生都队 组长博客: 博客链接 成员 学号 史恩泽(组长) 031702122 施金海 031702121 阮君曦 031702116 陈银山 031702137 李季城 031702 ...
- 为什么printf()用%f输出double型,而scanf却用%lf呢?
转:https://blog.csdn.net/bat67/article/details/52056057 示例:double x:scanf(“%f”,&x):输入“123.4”,输出x的 ...
- svn忽略obj
于是换成第二种方式 Properties => News => Other => svn:ignore 将你要过滤的文件夹放入文本框里面,此处因为要过滤的是bin和obj所以各占一行 ...
- 品优购商城项目(五)消息中间件 ActiveMQ
消息中间件用于降低各个项目模块的耦合,适用于不需要等待返回消息才能进入下一个业务环节的模块,以及实时要求性不高的业务模块. 一.JMS JMS(Java Messaging Service)是Java ...
- Qt QJson解析json数据
Qt QJson解析json数据 //加载根目录文件 void TeslaManageData::loadRootFolderFiles() { QNetworkAccessManager *mana ...