SQL开发中容易忽视的一些小地方(五)
背景:
索引分类:众所周知,索引分为聚集索引和非聚集索引。
索引优点:加速数据查询。
问题:然而我们真的清楚索引的应用吗?你写的查询语句是否能充分应用上索引,或者说你如何设计你的索引让它更高效?
经历:以前本人只知道索引的好处,但是是否能够真正让它发挥作用,并无太多理论,为些本人做了些DEMO,来简单说明下什么情况下才能充分利用索引。
案例:
这里建立一个学生表:有如下字段,此时表中没有建立任何索引。
CREATE TABLE [dbo].[student](
[ID] [int] IDENTITY(1,1) NOT NULL,--学生ID
[sUserName] [nchar](10) COLLATE Chinese_PRC_CI_AS NULL,--学生姓名
[sAddress] [varchar](200) COLLATE Chinese_PRC_CI_AS NULL,--学生地址
[classID] [int] NULL,--学生所属班级ID
[create_date] [datetime] NULL CONSTRAINT [DF_student_create_date] DEFAULT (getdate()) --入校时间
) ON [PRIMARY]
业务需求:
查询班级ID为9的所有学生的姓名和地址。
情况一:
--字段没有建立任何索引
select sUserName,sAddress from student
where classID=9
执行计划如下图:

结论:在没有任何索引的情况下,查询会选择全表扫描.
情况二:
给ID自增列创建一个聚集索引,我们很多情况下都是这样默认的,主键上就是聚集索引。同样的查询,不同的查询计划,发现此时虽然在输出列和条件中没有ID,但是查询选择了聚集查询.
执行计划图同图一。

情况三:在classID上创建非聚集索引。
结论:虽然条件列中出现了classID索引列,但是输出列中并没有创建任何索引,依然选用聚集扫描方式查询.
情况四:在sUserName上创建非聚集索引
结论:同上
情况五:继续在sAddress上创建非聚集索引
结论:同上
情况六:建立sUserName与sAddress的联合非聚集索引
结论:同上
情况七:在classID与sUserName上创建索引
结论:同上
情况八:在classID,sUserName,sAddress上创建联合非聚集索引
执行计划图如下:

结论:当条件中出现的列加上输出列和联合索引列完全匹配时全用上索引扫描.
情况九:删除所有索引,保留ID的聚集索引。以聚集索引列做为条件之一来查询.
select sUserName,sAddress from student
where ID=10021002
或者:select sUserName,sAddress from student
where ID=10021002 and classID=9
执行计划图:

所有情况总结:
1:当使用非聚集索引扫描时的IO情况:表 'student'。扫描计数 1,逻辑读取 70 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
2:当使用聚集索引扫描时的IO情况(条件中未出现聚集索引列):表 'student'。扫描计数 3,逻辑读取 8835 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
3:当使用聚集索引扫描时的IO情况(条件中出现聚集索引列) :表 'student'。扫描计数 1,逻辑读取 3 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
结论:
1:在没有正确的索引情况下,会增加表的扫描次数.
2:数据在查询时会先找匹配的索引.
1):如果在条件列中出现聚集索引列,则无论输出列是否建立索引都会按聚集索引查找(有聚集索引 ).
2):如果在条件列中没有出现聚集索引列,则查找匹配的非聚集索引,如果有匹配的索引则按相应索引查询,否则再扫描聚集索引(有聚集索引 ).
3):查找匹配的非聚集索引(没有聚集索引 ).
本文总结:
我只是简单的写了些关于索引使用的DEMO,在实际开发中要按实际情况来分析,有时并不能完全使用上索引,但是可以让查询产生最少的IO读取以及表扫描次数。
SQL开发中容易忽视的一些小地方(五)的更多相关文章
- SQL开发中容易忽视的一些小地方(一)
原文:SQL开发中容易忽视的一些小地方(一) 写此系列文章缘由: 做开发三年来(B/S),发现基于web 架构的项目技术主要分两大方面: 第一:C#,它是程序的基础,也可是其它开发语言,没有开发语言也 ...
- SQL开发中容易忽视的一些小地方(二)
原文:SQL开发中容易忽视的一些小地方(二) 目的:继上一篇:SQL开发中容易忽视的一些小地方(一) 总结SQL中的null用法后,本文我将说说表联接查询. 为了说明问题,我创建了两个表,分别是学生信 ...
- SQL开发中容易忽视的一些小地方(六)
原文:SQL开发中容易忽视的一些小地方(六) 本文主旨:条件列上的索引对数据库delete操作的影响. 事由:今天在博客园北京俱乐部MSN群中和网友讨论了关于索引对delete的影响问题,事后感觉非常 ...
- 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}}" ...
随机推荐
- testing and SQA_动态白盒測试
一.软件測试技术: 黑盒:在不知道程序内部结构,仅仅知道程序结构的情况下採用的測试技术或策略. 白盒:在知道程序内部结构的情况下採用的測试技术或策略. 两种測试方法从不同的角度出发,反映了软件的不同側 ...
- PHP socket类
没事的时候自己封装了一个socket类 功能非常easy和curl功能是一样的 class socketClass{ private $host; private $url; private $err ...
- HibernateReview Day1 - Introduction
Hibernate已经学过去大概有半个月了,然后默默的忘掉了……所谓Practice makes perfect. 我尽力重新拾起来. 1.什么是ORM 在介绍Hibernate之前,我们先学习下OR ...
- python学习笔记之11:图像用户界面
这里会介绍如何创建python程序的图像用户界面(GUI),也就是那些带有按钮和文本框的窗口等.目前支持python的所谓“GUI工具包”的有很多,本文简要介绍最成熟的跨平台pythonGUI工具包- ...
- 【数据结构&&等差数列】KMP简介和算法的实现(c++ && java)
KMP算法假定了解案件的原则,其实很easy. KMP算法简述 关于根据自己的理解在这里. KMP该算法由三个发明人的名称(Knuth.Morris.Pratt)的首字母组成,又称字符串查找算法. 个 ...
- 谈论高并发(二十二)解决java.util.concurrent各种组件(四) 深入了解AQS(二)
上一页介绍AQS其基本设计思路以及两个内部类Node和ConditionObject实现 聊聊高并发(二十一)解析java.util.concurrent各个组件(三) 深入理解AQS(一) 这篇说一 ...
- [笔记] C# Windows Phone 8 WP8 开发,判断目前网路是否可用。
原文:[笔记] C# Windows Phone 8 WP8 开发,判断目前网路是否可用. 常常我们在开发Windows Phone 8 App时会使用网路来读取网页的资料或其他开放平台的Json.X ...
- iOS Foundation 框架基类
iOS Foundation 框架基类 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转 ...
- ADO.NET连接方式
使用Command.DataReader和DataSet两种方法实现数据绑定 方法1:使用Command和DataReader SqlConnection con = new SqlConnectio ...
- 在WPF中使用PlaneProjection模拟动态3D效果
原文:在WPF中使用PlaneProjection模拟动态3D效果 虽然在WPF中也集成了3D呈现的功能,在简单的3D应用中,有时候并不需要真实光影的3D场景.毕竟使用3D引擎会消耗很多资源,有时候使 ...