SQL开发中容易忽视的一些小地方(五)

原文: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读取以及表扫描次数。

时间: 2024-11-12 01:35:05

SQL开发中容易忽视的一些小地方(五)的相关文章

SQL开发中容易忽视的一些小地方(一)

原文:SQL开发中容易忽视的一些小地方(一) 写此系列文章缘由: 做开发三年来(B/S),发现基于web 架构的项目技术主要分两大方面: 第一:C#,它是程序的基础,也可是其它开发语言,没有开发语言也就不存在应用程序. 第二:数据库,现在是信息化世界,大多数信息都可以通过数据库存储来交换信息.常与应用程序互相交流信息. 但在SQL开发应用时,我们往往只观注些常用的方法(insert delete select update),对些小细节方面(系统存储过程,函数的应用,优化分析)研究的并不多或者是

SQL开发中容易忽视的一些小地方(四)

原文:SQL开发中容易忽视的一些小地方(四) 本篇我想针对网上一些对于非聚集索引使用场合的某些说法进行一些更正. 下面引用下MSDN对于非聚集索引结构的描述. 非聚集索引结构: 1:非聚集索引与聚集索引具有相同的 B 树结构,它们之间的显著差别在于以下两点: * 基础表的数据行不按非聚集键的顺序排序和存储. * 非聚集索引的叶层是由索引页而不是由数据页组成. 2:非聚集索引行中的行定位器或是指向行的指针,或是行的聚集索引键,如下所述: * 如果表是堆(意味着该表没有聚集索引),则行定位器是指向行

SQL开发中容易忽视的一些小地方( 三)

原文:SQL开发中容易忽视的一些小地方( 三) 目的:这篇文章我想说说我在工作中关于in和union all 的用法. 索引定义 : 微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引.簇集索引)和非聚集索引(nonclustered index,也称非聚类索引.非簇集索引). SARG的定义:用于限制搜索的一个操作,因为它通常是指一个特定的匹配,一个值得范围内的匹配或者两个以上条件的AND连接.形式如下: 列名 操作符 <常数 或 变量>或<

SQL开发中容易忽视的一些小地方(二)

原文:SQL开发中容易忽视的一些小地方(二) 目的:继上一篇:SQL开发中容易忽视的一些小地方(一) 总结SQL中的null用法后,本文我将说说表联接查询. 为了说明问题,我创建了两个表,分别是学生信息表(student),班级表(classInfo).相关字段说明本人以SQL创建脚本说明: 测试环境:SQL2005 CREATE TABLE [dbo].[student]( [ID] [int] IDENTITY(1,1) NOT NULL, [sUserName] [nchar](10) C

SQL Server 中关于 @@error 的一个小误区

原文:SQL Server 中关于 @@error 的一个小误区 在SQL Server中,我常常会看到有些前辈这样写: if(@@error<>0) ROLLBACK TRANSACTION T else COMMIT TRANSACTION T 一开始,我看见别人这么写,我就想当然的以为它只是个计数器,每当检测到一处错误时,@@error的值+1,不过就因为这个理所当然,所以杯具了... 实际上,它并不是一个计数器,它是一个动态的值,动态的标识最后一条SQL命令执行的结果,如果成功则为0,

jQuery开发中容易忽视的错误

1.引用jQuery库文件的<script>标签,必须放在引用自定义脚本文件的<script>标签之前,否则,就会发生找不到对象:最好在<head>元素中,把引入样式表的<link />放在<script>标签前面:有时候其他的javascript库也会用$符号,为了不冲突,可以使用.noConflict()方法把控制权交给别的库.    <script src="prototype.js" type="tex

ios开发——开发总结篇&amp;开发中常见错误和警告总结(五)

开发中常见错误和警告总结(五) 一.Missing file xxx 如果你在finder中删除了工程里面的文件,xcode上会出现一个警告,Missing file xxx, 有个警告在那恨事不自在.上网着了下,发现了如下解决方法: 1.打开terminal, cd 到刚才你删除的文件的文件夹,就是xcode提示你missing的文件夹 2.执行 svn delete missFileName  二.LLVM GCC Warning 4.3默认使用的是ARC编译,不是原来的GCC编译,所以你编

Web开发中致命的8个小错误

现在,有越来越多所谓的"教程"来帮助我们提高网站的易用性.本文收集了一些在Web开发中容易出错和被忽略的小问题,并且提供了参考的解决方案,以便于帮助Web开发者更好的完善网站. 通过避免下面这些小错误,可以使得我们的网站变得更为友好. 错误1:表单的label标签跟表单字段没有关联 利用"for"属性允许用户单击label也可以选中表单中的内容.这可以扩大复选框和单选框的点击区域,非常实用. 错误2:logo图片没有链接到主页 点击网站logo就能转到主页已经成为了

PL/SQL开发中动态SQL的使用方法

一般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使用SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使用,要想实现在PL/SQL中使用DDL语句及系统控制语句,可以通过使用动态SQL来实现. 首先我们应该了解什么是动态SQL,在Oracle数据库开发PL/SQL块中我们使用的SQL分为:静态SQL语句和动态SQL语句.所谓静态SQL指在PL/SQL块中使用的SQL语句在编译时是明确的,执行的是确定对象.而动态SQL是指在PL/SQL块编译时SQL语句是不确定的,如根