Key Lookup开销过大导致聚集索引扫描
以前总结过一篇文章SQL SERVER中什么情况会导致索引查找变成索引扫描 介绍了几种索引查找(Index Seek)变成索引扫描(Index Scan)的情形。昨天写一篇文章的时候,也遇到了一个让人奇怪的执行计划。一时没有想明白为什么优化器会选择聚集索引扫描。案例详情请见SQL Server OPTION (OPTIMIZE FOR UNKNOWN) 测试总结 。 如下所示,测试环境为SQL Server 2014,数据库为AdventureWorks2014
CREATE PROCEDURE test (@pid int)
AS
SELECT * FROM [Sales].[SalesOrderDetail]
WHERE ProductID = @pid OPTION (OPTIMIZE FOR UNKNOWN);
[Sales].[SalesOrderDetail]的索引信息如下如下。其实这里优化器选择聚集索引扫描是因为Cost缘故。因为走非聚集索引查找(Index Seek)的话,Key Lookup的开销较大。整体开销比聚集索引扫描还大。我们可以测试验证一下
如下所示,我们新增一个SQL语句,强制其走索引查找(具体索引为IX_SalesOrderDetail_ProductID),然后执行对比查看执行计划的开销
ALTER PROCEDURE test (@pid int)
AS
SELECT * FROM [Sales].[SalesOrderDetail]
WHERE ProductID = @pid OPTION (OPTIMIZE FOR UNKNOWN);
SELECT * FROM [Sales].[SalesOrderDetail] WITH (INDEX =IX_SalesOrderDetail_ProductID)
WHERE ProductID = @pid;
GO
如下测试所示,两种实际执行计划的开销比为 22% VS 78%。 所以优化器肯定会选开销小的执行计划。也就是说如果优化器发现当索引查找时,如果Key Lookup开销过大,那么优化器会选择聚集索引索引扫描。 这个案例就是一个活生生的案例。 也许有人会反问:不是Index Seek效率表Index Scan要高吗?你这有点不合逻辑,注意,这个特定条件下,虽然Index Seek变成 Index Scan,但是你注意一下上下文,索引变了, 从IX_SalesOrderDetail_ProductID变成了聚集索引PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID 。
总结: 任何现象背后都有一定的规律,有时候,只要你静下心来,仔细分析一下。就能一窥究竟。如果总是不问为什么,那么你总是不了解背后原理!也就永远止步不前!
Key Lookup开销过大导致聚集索引扫描的更多相关文章
- Sql Server 聚集索引扫描 Scan Direction的两种方式------FORWARD 和 BACKWARD
最近发现一个分页查询存储过程中的的一个SQL语句,当聚集索引列的排序方式不同的时候,效率差别达到数十倍,让我感到非常吃惊 由此引发出来分页查询的情况下对大表做Clustered Scan的时候, 不同 ...
- Sql Server之旅——第四站 你必须知道的非聚集索引扫描
非聚集索引,这个是大家都非常熟悉的一个东西,有时候我们由于业务原因,sql写的非常复杂,需要join很多张表,然后就泪流满面了...这时候就 有DBA或者资深的开发给你看这个猥琐的sql,通过执行计划 ...
- 陷阱~SQL全表扫描与聚集索引扫描
SqlServer中在查询时,我们为了优化性能,通常会为where条件的字段建立索引,如果条件比较固定还会建立组合索引,接下来,我们来看一下索引与查询的相关知识及相关陷阱. SQL表自动为主键加聚集索 ...
- SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析
在SQL SERVER的查询语句中使用OR是否会导致不走索引查找(Index Seek)或索引失效(堆表走全表扫描 (Table Scan).聚集索引表走聚集索引扫描(Clustered Index ...
- SQL SERVER中关于OR会导致索引扫描或全表扫描的浅析 (转载)
在SQL SERVER的查询语句中使用OR是否会导致不走索引查找(Index Seek)或索引失效(堆表走全表扫描 (Table Scan).聚集索引表走聚集索引扫描(Clustered Index ...
- SQLSERVER聚集索引与非聚集索引的再次研究(下)
SQLSERVER聚集索引与非聚集索引的再次研究(下) 上篇主要说了聚集索引和简单介绍了一下非聚集索引,相信大家一定对聚集索引和非聚集索引开始有一点了解了. 这篇文章只是作为参考,里面的观点不一定正确 ...
- 索引深入浅出(4/10):非聚集索引的B树结构在聚集表
一个表只能有一个聚集索引,数据行以此聚集索引的顺序进行存储,一个表却能有多个非聚集索引.我们已经讨论了聚集索引的结构,这篇我们会看下非聚集索引结构. 非聚集索引的逻辑呈现 简单来说,非聚集索引是表的子 ...
- MySQL索引的原理,B+树、聚集索引和二级索引的结构分析
索引是一种用于快速查询行的数据结构,就像一本书的目录就是一个索引,如果想在一本书中找到某个主题,一般会先找到对应页码.在mysql中,存储引擎用类似的方法使用索引,先在索引中找到对应值,然后根据匹配的 ...
- SQLServer中重建聚集索引之后会影响到非聚集索引的索引碎片吗
本文出处:http://www.cnblogs.com/wy123/p/7650215.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...
随机推荐
- ④品茶看<Servlet&JSP>-EL表达式
前言 今早,概率课偷了下小懒写的: 泡一杯红茶,ACM集训前,写篇博客记录记录EL表达式. #EL介绍 ①EL 语法 ②访问JavaBean等 ③EL隐式对象 ④EL运算符 EL介绍 EL 全名为Ex ...
- centos 7 linux 安装与卸载 tomcat 7
一.声明 本文采用操作系统版本: Centos 7 Linux系统 版本源:CentOS-7-x86_64-DVD-1708.iso 官网下载地址:http://isoredirect.centos. ...
- Linux下获取java堆栈文件并进行分析
当服务器内存飙升或者cpu负载飙升的时候,可以使用如下步骤排查问题: 1.终端输入top命令,键盘大写的情况下按P(cpu负载率从高到低排序)或者M(内存使用率从高到低排序),可以查看导致cpu或者内 ...
- 南大算法设计与分析课程OJ答案代码(1)中位数附近2k+1个数、任意两数之和是否等于给定数
问题1 用来测试的,就不说了 问题2:中位数附近2k+1个数 给出一串整型数 a1,a2,...,an 以及一个较小的常数 k,找出这串数的中位数 m 和最接近 m 的小于等于 m 的 k 个数,以及 ...
- redis的Pub/Sub
redis的Pub/Sub机制类似于广播架构,Subscriber相当于收音机,可以收听多个channel(频道),Publisher(电台)可以在channel中发布信息. 命令介绍 PUBLISH ...
- Linux--Introduction and Basic commands(Part one)
Welcome to Linux world! Introduction and Basic commands--Part one J.C 2018.3.11 Chapter 1 What Is Li ...
- Python在Office 365 开发中的应用
我在昨天发布的文章 -- 简明 Python 教程:人生苦短,快用Python -- 中提到了Python已经在Office 365开发中全面受支持,有不同朋友留言或私信说想了解更加详细的说明,所以特 ...
- 【译】《Clean C#》
本文是<Clean C#>一书译文的序言,阅读译文请移步至:<Clean C#>译文. <Clean C#>的副标题是Readable,Maintainable,P ...
- Windows server 2008 R2配置多个远程连接
1.右键计算机属性——远程设置——出现系统属性对话框——选择“远程”选项卡,按如下图操作:. 2.默认只有administrator具有远程桌面的权限,其他用户都没有权限远程桌面连接服务器.因此,我们 ...
- mysql left join的深入探讨
即使你认为自己已对 MySQL 的 LEFT JOIN 理解深刻,但我敢打赌,这篇文章肯定大致也许可能让你学会点东西! ON 子句与 WHERE 子句的不同 一种更好地理解带有 WHERE ... I ...