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
![](https://www.aspxhome.com/images/zang.png)
![](https://www.aspxhome.com/images/jiucuo.png)
猜你喜欢
- 一.axisaxis就是指定轴。三维数组可看作元素是二维数组的一维数组,二维数组可看作元素是一维数组的一维数组 。(这么理解就舒服了!)例:
- 废话还是说太多了 直接上代码import randomimport sys# 牌面列表card_code = ['A', &
- 如下所示:#Copyright (c)2017, 东北大学软件学院学生# All rightsreserved#文件名称:a.py# 作 者
- 本文为大家分享了python实现学生管理系统的具体代码,供大家参考,具体内容如下1.0版本学生管理系统''' 1.添
- 本文实例讲述了Python标准库shutil用法。分享给大家供大家参考,具体如下:shutil模块提供了许多关于文件和文件集合的高级操作,特
- 在很多应用程序开发中,需要记录某些数据表的历史记录或修改痕迹,以便日后出现数据错误时进行数据排查。这种业务需求,我们可以通过数据库的触发器来
- 1、对继承的理解继承(Inheritance) :代码复用的高级抽象继承是面向对象设计的精髓之一实现了以类为单位的高级抽象级别代码复用继承是
- 1. 序列类型定义序列是具有先后关系的一组元素序列是一维元素向量,元素类型可以不同类似数学运算序列:S0,S1,…,S(n-1)元素间由序号
- 前两天,编辑建议我去当当和卓越申请个用户,在网站上放上我的书的链接,这样还可以拿到一些反点儿,于是我兴冲冲地跑到几个网站上去看,却只在卓越(
- 本文介绍了计算多个订单的核销金额的全部过程,运行数据库环境:SQL SERVER 2005,下面跟大家分享一下。下图是一张订单明细表,现有金
- 什么是生产者消费者模型在 工作中,大家可能会碰到这样一种情况:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以
- 前言最近在学习python,发现了解线程信号量的基础知识,对深入理解python的线程会大有帮助。所以本文将给大家介绍Python3.X线程
- 大概来介绍一下 Django Allauth 改造的期间遇到的一些问题和改造方法,在此之前我只想说——Django Allauth 是屑。为
- 这是经常用的一个分页存储过程 希望大家指点不足 代码如下:USE [a6756475746] GO /****** Object
- 一、写在前面我从未想过自己会写python系列的自动化文章,有些同学会问,那你现在为什么又开始写了?不止一个人找过我,问我可以写一些Pyth
- 前言主要介绍OpenCV中的分水岭算法、图像金字塔对图像进行分割的方法。一、使用分水岭算法分割图像分水岭算法的基本原理为:将任意的灰度图像视
- 我试了网上提供的一些方法都不行,最后还是自己用SQL解决了些问题。 1 在查询分析器里面选中出问题的数据库,然后输入: Exec sp_co
- 复制表结构及其数据下面这个语句会拷贝数据到新表中。注意:这个语句其实只是把select语句的结果建一个表,所以新表不会有主键,索引。crea
- 最近邻:import cv2import numpy as npdef function(img): height,width,channe
- 小编今天写下关于后台管理员权限的分配自己的思路想法<?php /**reader * 小编的思想比较简单实现的功能