SQL开发中容易忽视的一些小地方(六)
本文主旨:条件列上的索引对数据库delete操作的影响。
事由:今天在博客园北京俱乐部MSN群中和网友讨论了关于索引对delete的影响问题,事后感觉非常汗颜,因为我的随口导致错误连篇。大致话题是这样的,并非原话:
[讨论:] delete course where classID=500001 classID上没有创建任何索引,为了提高删除效率,如果在classID上创建一个非聚集索引会不会提高删除的效率呢?
我当时的观点:不能。
我当时的理由:数据库在执行删除时,如果在classID上创建了非聚集索引,首先按这个非聚集索引查找数据,找到索引行后,根据索引行后面带的聚集索引地址最后找到真正的物理数据行,并且执行删除,这个过程看起来没有作用,只能创建聚集索引来提高删除效率,因为如果classID是聚集索引,那么直接聚集索引删除,此时的效率最高。
下班后对这个话题再次想了下,觉的自己的观点都自相矛盾,既然知道删除时,会在条件列上试图应用已经存在的索引,那么为什么创建非聚集索引会无效呢?如果表的数据相当大,classID上如果没有任何索引,查找数据时就要执行表扫描,而表扫描的速度是相当慢的,为此为了证明下这个问题,我特意做了一个示意性的实验。
创建两个表course 和course2,创建语句如下,它们唯一的区别就在于索引,course表中classID上创建了非聚集索引,而course2上没有创建任何索引。
CREATE TABLE [dbo].[course](
[ID] [int] IDENTITY(1,1) NOT NULL,
[sCourseName] [nchar](10) COLLATE Chinese_PRC_CI_AS NULL,
[classID] [int] NULL,
CONSTRAINT [PK_CKH] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
--创建索引
create index IX_classID
on course(classID) CREATE TABLE [dbo].[course2](
[ID] [int] IDENTITY(1,1) NOT NULL,
[sCourseName] [nchar](10) COLLATE Chinese_PRC_CI_AS NULL,
[classID] [int] NULL,
CONSTRAINT [PK_CKH2] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
实验过程:
第一步:分别给两个表插入相当的数据1000行,然后删除第500条记录。
delete course
where classID=500
delete course2
where classID=500
执行计划图如下:我们可以看到在执行删除时,数据库分为三部分:
1:查找到要删除的数据行;
2:包含一个top操作。
3:执行聚集索引删除。
区别一:由于course表的classID上创建了索引,所以查找时按PK_classID来查找,course2表的classID由于没有任何的索引,为了查找到要删除的数据行,就只能按聚集索引查找,此时实际上是全表扫描。
区别二:系统开销不同,让人意外的是,结果表明好像白天的观点是正确的,创建了索引的coure表在开销上比没有创建索引的course2还大一点。
分析区别二的原因:我们来看下聚集索引删除的具体内容,下面是在条件列classID上创建了非聚集索引的表course表在发生删除时的执行计划图,它在删除后需要维护索引PK_classID,占用部分的系统开销。而没有创建索引的表course2由于没有索引维护的额外开销,所以反而占优势。
第二步:分别给两个表插入相当的数据10000行,然后删除第5000条记录。
区别同第一步。难道我的观点真的正确?
第三步:分别给两个表插入相当的数据100000行,然后删除第50000条记录。执行计划图如下:
区别一:同前两步的区别一。
区别二:系统开销不同,此时会发现创建了索引的course表在开销上占5%,而没有创建索引的course2表占了95%,这可是10倍的区别啊。
第四步:分别给两个表插入相当的数据1000000行,然后删除第500000条记录。
区别同第三步。
总结:当删除语句的条件列没有创建索引时分两种情况:
第一:数据量较小,我测试时在10000以下,此时两者的差别不大,反而会因为创建了索引而引起磁盘开销。开销差距不大是因为数据量小时,即使全表扫描速度也不慢,此时索引的优势并不明显。
第二:数据量较大,我测试时在100000以上,此时两者的差别较大。条件列创建了索引的表明显效率高。
第三:归根结底,系统的主要开销还是在删除的第一步,查找数据行上。能更快查找到删除行的方案效率最高。
SQL开发中容易忽视的一些小地方(六)的更多相关文章
- SQL开发中容易忽视的一些小地方(五)
原文:SQL开发中容易忽视的一些小地方(五) 背景: 索引分类:众所周知,索引分为聚集索引和非聚集索引. 索引优点:加速数据查询. 问题:然而我们真的清楚索引的应用吗?你写的查询语句是否能充分应用上索 ...
- SQL开发中容易忽视的一些小地方(一)
原文:SQL开发中容易忽视的一些小地方(一) 写此系列文章缘由: 做开发三年来(B/S),发现基于web 架构的项目技术主要分两大方面: 第一:C#,它是程序的基础,也可是其它开发语言,没有开发语言也 ...
- SQL开发中容易忽视的一些小地方(二)
原文:SQL开发中容易忽视的一些小地方(二) 目的:继上一篇:SQL开发中容易忽视的一些小地方(一) 总结SQL中的null用法后,本文我将说说表联接查询. 为了说明问题,我创建了两个表,分别是学生信 ...
- SQL开发中容易忽视的一些小地方( 三)
原文:SQL开发中容易忽视的一些小地方( 三) 目的:这篇文章我想说说我在工作中关于in和union all 的用法. 索引定义 : 微软的SQL SERVER提供了两种索引:聚集索引(cluster ...
- SQL开发中容易忽视的一些小地方(四)
原文:SQL开发中容易忽视的一些小地方(四) 本篇我想针对网上一些对于非聚集索引使用场合的某些说法进行一些更正. 下面引用下MSDN对于非聚集索引结构的描述. 非聚集索引结构: 1:非聚集索引与聚集索 ...
- PL/SQL开发中动态SQL的使用方法
一般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使用SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使用,要想实现在PL/SQL中使用DDL语句及系统控制语句,可以通过使 ...
- SQL Server 中关于 @@error 的一个小误区
在SQL Server中,我常常会看到有些前辈这样写: ) ROLLBACK TRANSACTION T else COMMIT TRANSACTION T 一开始,我看见别人这么写,我就想当然的以为 ...
- ASP.NET MVC 开发中遇到的两个小问题
最近在做一个网站,用asp.net MVC4.0来开发,今天遇到了两个小问题,通过查找相关渠道解决了,在这里把这两个问题写出来,问题非常简单,不喜勿喷,mark之希望可以给遇到相同问题的初学者一点帮助 ...
- 微信小程序开发中遇到的几个小问题
本地图片不显示,开发工具运行是没问题的,但真机调试却显示不了 item.img = '/goods/img/图片.png' <image src="{{item.img}}" ...
随机推荐
- android uiautomator自己主动化測试
前提是自己电脑上配置好JDK,android和ant的环境 1.命令行下进入\Android-sdk\tools\文件夹下,执行命令: android list 查看相应android版本 ...
- Very Deep Convolutional Networks for Large-Scale Image Recognition
Very Deep Convolutional Networks for Large-Scale Image Recognition 转载请注明:http://blog.csdn.net/stdcou ...
- Java学习之路:详细解释Java解析XML四种方法
XML如今已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便. 对于XML本身的语法知识与技术细节,须要阅读相关的技术文献,这里面包含的内容有DO ...
- 泛泰A870L/K/S第三版官方4.4.2原来的系统卡刷机包 (愿自己主动ROOT)
采用suky大神ota具,来自官方的拍摄OTA包裹,未做任何改动, 使用官方recovery,还是我的头发中国TWRP 2.7.1.1 for A870 (己主动ROOT. 自己主动ROOT完后就自己 ...
- sql server基本流程语句
- Java 并发专题 : CyclicBarrier 打造一个安全的门禁系统
继续并发专题~ 这次介绍CyclicBarrier:看一眼API的注释: /** * A synchronization aid that allows a set of threads to all ...
- AutoFac使用方法总结:Part III
生命周期 AutoFac中的生命周期概念非常重要,AutoFac也提供了强大的生命周期管理的能力. AutoFac定义了三种生命周期: Per Dependency Single Instance P ...
- 重新想象 Windows 8 Store Apps (32) - 加密解密: 非对称算法, 数据转换的辅助类
原文:重新想象 Windows 8 Store Apps (32) - 加密解密: 非对称算法, 数据转换的辅助类 [源码下载] 重新想象 Windows 8 Store Apps (32) - 加密 ...
- cocos2d之Box2D详细说明 鼠标联合实现
cocos2d之Box2D具体解释 鼠标关节实现 DionysosLai2014-5-7 我们常常要移动物理世界中的某个物体,例如说石头.木块等.假设我们直接改变这些物体的位置,让这些物体尾随我们手指 ...
- 认识Backbone (三)
Backbone.Collection(集合) collection是model对象的一个有序的组合,我们可以在集合上绑定 "change" 事件,从而当集合中的模型发生变化时f ...