02-如何优化数据库查询脚本(2)

2019-01-19 10:31

3.1.2. 非聚集索引

非聚集索引与聚集索引具有相同的 B 树结构,但是非聚集索引具有独立于数据行的结构。非聚集索引包含非聚集索引键值,并且每个键值项都有指向包含该键值的数据行的指针,这个指针称为行定位器。

可以向非聚集索引行中添加非键值列,称之为包含性列。也就是可以把一些常用的字段放到索引中。例如在用户登陆时,我们把用户名建为索引并把用户密码添加到包含性列,那么我们跟据用户名查询用户密码时只需要查询用户名索引即可,而不需要跟据定位器查询聚集索引。如下图所示:

没有添加包含性列的执行计划如下所示:

添加包含性列的执行计划如下所示:

我们看下系统里面的另外一个查询语句,在考试列表页面需要加载考试未正常提交的考试成绩脚本如下所示:

select exam_grade.*,exam_exam.* from exam_grade

inner join exam_exam on exam_exam.exam_uid = exam_grade.exam_uid inner join nv_folder on(nv_folder.folder_uid = exam_exam.folder_uid) left join exam_paper on exam_paper.paper_uid=exam_grade.paper_uid where exam_grade.user_uid = '01BABEB5-40A8-49AB-8DBF-7A9478C814A9'

and (exam_grade.grade_status_code = 'examing') and (exam_exam.exam_class_code = 'exam')

在这个查询语句里面查询对exam_grade的过滤条件有两个user_uid和grade_status_code。我们已经在表中添加user_uid的索引。以下为I/O的执行结果:

通过上图我们可以看出针对表exam_grade的逻辑读取次数达到94次,执行效率不高。那么我们把grade_status_code添加user_uid索引的包含性列之后,exam_grade的逻辑读取次数只有4次,如下图所示:

数据库中非聚集索引的数据结构如下图所示:

非聚集索引中每一行数据的内容如下图所示:

3.1.3. 索引统计信息

数据库是如何选择一种执行计划的呢? 数据库怎么知道什么时候该用索引或者用哪个索引? 对于数据库来说,每当要执行一个查询时,都要首先检查有没有这个查询的执行计划是否存在缓存中,如果没有,则要生成一个执行计划, 具体在产生执行计划时,并不是看有哪些索引可用(随机选择),而是会参考一种被称为【索引统计信息】的数据。 如果您仔细地看一下前面的执行计划或者执行过程表格,会发现数据库能预估每个步骤所产生的数据量, 正是因为数据库能预估这些数据量,数据库才能选择一个它认为最合适的方法去执行查询过程, 此时【索引统计信息】就能告诉数据库这些数据。

查看索引统计信息的脚本如下所示: dbcc show_statistics (表名, 索引名)

3.1.4. 参考

索引

http://msdn.microsoft.com/zh-cn/library/ms189271(v=sql.105)

3.2. 数据查询方式

数据库对表内容的查询有以下几种方式,每种方式的数据库性能差别比较大。也就是说我们优化脚本主要是改变数据库的查询方式。

? Table Scan:遍历整个表,查找所匹配的记录行。这个操作将会一行一行的检查,

当然,效率也是最差的。

? Index Scan:根据索引,从表中过滤出来一部分记录,再查找所匹配的记录行,显

示比第一种方式的查找范围要小,因此比【Table Scan】要快。

? Index Seek:根据索引,定位(获取)记录的存放位置,然后取得记录,因此,比

起前二种方式会更快。

? Clustered Index Scan:和Table Scan一样。注意:不要以为这里有个Index,就

认为不一样了。 其实它的意思是说:按聚集索引来逐行扫描每一行记录,因为记录就是按聚集索引来顺序存放的。 而Table Scan只是说:要扫描的表没有聚集索引而已,因此这二个操作本质上也是一样的。

? Clustered Index Seek:直接根据聚集索引获取记录,最快!

3.3. 执行计划

对于SQL Server所接受到的每一个查询,查询处理器的首要任务就是产生一个计划,

这个计划就描述了如何去执行查询,之后就由存储引擎去执行这个计划了。这个计划称为执行计划。前面已经提到查询处理器是跟据索引统计信息来匹配最适合的执行计划,具体匹配的过程不在本文档的讨论范围之内。

3.3.1. 显示执行计划

使用SSMS(SQL Server Management Studio)我们可以图形化的显示脚本的执行计划,在SSMS的工具栏中可以通过“显示估计的执行计划”和“包括实际的执行计划”按钮显示脚本的执行计划。

? 显示估计的执行计划:点击此按钮SSMS会显示估计的执行计划

? 包括实际的执行计划:选中此按钮,在执行脚本时SSMS会显示实际执行时的执行

计划。

显示执行计划的按钮如下图所示:

3.3.2. 了解执行计划

执行计划是数据库数据查询和脚本执行的方法,所以执行计划最能提现出SQL脚本执行效率的高低。下面我们通过一个简单的SQL语句来看看执行计划能给我们反馈什么样的信息。下面是一条通过试卷Uid获取试卷中试题列表的SQL语句。脚本的执行计划如下图所示:

按照从右到左、从上到下的方式阅读 SQL Server Management Studio 中的图形执行计划输出。将显示所分析的批处理中的每个查询,包括每个查询的开销占批处理总开销的百分比。从上图中我们至少可以得到4个有用的信息:

1. 节点“[exam_paper_node].[PK_exam_paper_node]”的扫描占用了95%的开销,

一般来说开销越高,执行效率就越低

2. 每个节点输出的数据量大小,SqlServer的执行计划是用“线条粗细”来表示的,

因此也很容易地从分辨出来

3. 每一个节点执行的动作,如:聚集索引扫描

4. 提示缺少的索引,如果数据有检测到有缺丢的索引,那么会在执行计划中提示

在图形化的执行计划中,把鼠标放到执行计划的节点上,会显示当前节点执行的详细信息。如下图所示:

执行计划各属性值如下表所示:

工具提示项 物理运算符 说明 使用的物理运算符,例如 Hash Join 或 Nested Loops。以红色显示的物理运算符表示查询优化器已发出警告,例如丢失列统计信息或丢失联接谓词。这可能导致查询优化器选择比预期的效率低的查询计划。有关列统计信息的详细信息,请参阅使用统计信息提高查询性能。 与物理运算符匹配的逻辑运算符,如 Inner Join 运算符。逻辑运Logical Operation


02-如何优化数据库查询脚本(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:电大法学专科《婚姻家庭法学》期末考试问答题、案例分析题题库

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: