SQL Server里书签查找的性能伤害
作者:Woodytu 发布时间:2024-01-13 08:19:05
在我的博客上,以前我经常谈到SQL Serverl里的书签查找,还有它们带来的很多问题。在今天的文章里,我想从性能角度进一步谈下书签查找,还有它们如何拉低你整个SQL Server性能。
书签查找——反复循环
如果你的非聚集索引不是个覆盖非聚集索引,SQL Server的查询优化器会引入书签查找。对于从非聚集索引你返回的每一行,SQL Server需要在聚集索引里或堆表里进行额外的查找操作。
例如当你的的聚集索引包含3层,为了返回必要的信息,对于每一行,你需要3页额外的读取。因此,查询优化器再执行计划里选择书签查找操作,仅在有意义的时候发生——基于你查询的选择度。下图展示了有书签查找操作的执行计划。
通常人们不会太关注书签查找,因为它们只执行几次。如果你的查询选择度太低,查询优化器会用聚集索引扫描或表扫描运算符直接扫描整个表。但只在SQL Server重用缓存的执行计划,这个计划是有多次不同运行值,包含书签查找的(基于最初提供的输入值),因此这个情况很容易发生,书签查找反复执行。
为了演示这个性能问题,接下来的查询我指定查询优化器使用特定的非聚集索引。查询本身返回80000行,因为对于每个查询执行,SQL Server需要进行书签查找80000次——反复执行。
CREATE PROCEDURE RetrieveData
AS
SELECT * FROM Table1 WITH (INDEX(idxTable1_Column2))
WHERE Column3 = 2
GO
下图展示了查询执行后的实际执行计划。
执行计划看起来非常恐怖(查询优化器甚至启用了并行计划!),因为书签查找运算符这里执行了80000次,查询本身产生了超过165000个逻辑读!(逻辑读个数可以从STATISTIC IO里获取)。
接下来向你展示下,当你有很多并行用户执行这个糟糕查询时,SQL Server会发生什么。我会使用ostress.exe(RML工具的一部分)来模拟100个并行用户的查询。
ostress.exe -Q”EXEC BookmarkLookupsPerformance.dbo.RetrieveData” -n100 -q
在我的测试系统上花费了近15秒来完成100个并行查询。在此期间,CPU占用很高,因为SQL Server需要嵌套循环运算符来进行书签查找操作。嵌套循环操作当然很占CPU资源。
现在让我们修改索引设计,为这个查询创建覆盖非聚集索引。有了非聚集索引,查询优化器不需要再执行计划里进行书签查找。一个非聚集索引查找就可以返回同样的结果:
CREATE NONCLUSTERED INDEX idxTable1_Column2 ON Table1(Column3)
INCLUDE (Column2)
WITH (DROP_EXISTING = ON)
GO
这次当我们再次用ostress.exe执行同个查询,我们看到每个查询在5秒内完成。和我们刚才看到的15秒有很大的区别。这就是覆盖非聚集索引的威力:在我们查询里气门请求的数据都可以在非聚集索引里直接找到,因此书签查找就可以避免。
小结
在这个文章里我向你展示了不好的书签查找会伤及性能。因此,对于重要的查询快速完成查询非常重要——而使用并行的书签查找的执行计划并不是好的选择。这里覆盖非聚集索引可以帮到你。下次设计索引时可以考虑下这个方法。
来源:http://www.cnblogs.com/woodytu/p/6586190.html


猜你喜欢
- 介绍舍友从网上下载的word题库文档很乱,手动改了大半天才改了一点,想起python是大名鼎鼎的自动化脚本,于是乎开始了python对wor
- 表示文字链接最清楚的方式是“蓝色文字+下划线”,这是在浏览器发展过程中形成的。这个问题大家都说过很多次了,我也曾经说过。然而,这样的规范却总
- 本文实例讲述了Python实现的计算器功能。分享给大家供大家参考,具体如下:源码:# -*- coding:utf-8 -*-#! pyth
- 经过1个周的摸索和查阅资料,终于搞定VUE3中自定义指令,实现按钮级别的权限控制。当然,只是简单的对按钮进行隐藏和删除的dom操作比较容易,
- 如果没有设置分页,django-rest-framework 会将所有资源类表序列化后返回,如果资源很多,就会对网站性能造成影响。为此,我们
- 定义返回单值def my_abs(x): if x >= 0: return x &
- 我们在使用selenium库调用Chromedriver.exe时需要很多的配置参数下面列出了常用参数chrome_options.add_
- 目录循环加判断retrying我们在程序开发中,经常会需要请求一些外部的接口资源,而且我们不能保证每次请求一定会成功,所以这些涉及到网络请求
- vue3使用computed获取vuex里数据不再是vue2.0里什么mapGetter,mapState那些复杂的获取方式,vue3.0里
- var str='1250' ; alert( Number(str) ); //得到1250 alert(parseInt
- 一、Cookie的使用1、什么是Cookie我们都知道,HTTP 协议是无状态的,也就是说,在一次请求响应结束后,服务端不会保留任何对方状态
- 前言多线程一般用于同时调用多个函数,cpu时间片轮流分配给多个任务。 优点是提高cpu的使用率,使计算机减少处理多个任务的总时间;缺点是如果
- 基本的字符串位置查找方法Python 查找字符串使用 变量.find("要查找的内容"[,开始位置,结束位置]),开始位
- 1.socket黏包问题原理黏包:指数据与数据之间没有明确的分界线,导致不能正确的读取数据。应用数据想要发送数据就必须将数据交给操作系统,而
- 相信用过Gmail的人都知道Gmail有一个草稿自动保存的功能,每过一段时间,Gmail都会自动保存邮件草稿,这样在一些突 * 况下就能快速地
- 当项目里用npm安装了babel-cli之类的包时,webstorm在索引node_modules文件时,会卡死接近这个问题的办法是把nod
- date("yyyyMMdd",time()) date() 函数功能:用于格式化时间,返回一个字符串。&nb
- 就在刚才,我给GMAIL安装了Twitter插件。安装完插件后,Gmail提示我要连接Twitter的账号才能使用:我顺着提示操作下去,就看
- 技术背景本文主要涵盖两个领域的知识点:python的魔法函数和量子计算模拟,我们可以通过一个实际的案例来先审视一下这两个需求是如何被结合起来
- 我们有理由相信采用新的内核版本(2.2.16-3 smp)也应该有性能的提升: OS2: Newer minor version kerne