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 (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...
随机推荐
- spark最新源码下载并导入到开发环境下助推高质量代码(Scala IDEA for Eclipse和IntelliJ IDEA皆适用)(以spark2.2.0源码包为例)(图文详解)
不多说,直接上干货! 前言 其实啊,无论你是初学者还是具备了有一定spark编程经验,都需要对spark源码足够重视起来. 本人,肺腑之己见,想要成为大数据的大牛和顶尖专家,多结合源码和操练编程. ...
- 项目ITP(五) spring4.0 整合 Quartz 实现任务调度
前言 系列文章:[传送门] 项目需求: 二维码推送到一体机上,给学生签到扫描用.然后需要的是 上课前20分钟 ,幸好在帮带我的学长做 p2p 的时候,接触过.自然 quartz 是首选.所以我就配置了 ...
- windows系统下发布python模块到pypi
1. 在pypi.python.org网站注册一个用户,记住用户名和密码. 2. 编写需要上传模块的源代码,文件名为:skyersfirstpythonmodule.py 3. 新建文件夹,名称为sk ...
- MySQL SQL语句执行顺序
MySQL的语句一共分为11步,如下图所标注的那样,最先执行的总是FROM操作,最后执行的是LIMIT操作.其中每一个操作都会产生一张虚拟的表,这个虚拟的表作为一个处理的输入,只是这些虚拟的表对用户来 ...
- 微信公众号开发模型WeChat
模型:WeChat (回复参考weiphp) <?php namespace Org; /** * 微信开发工具类 * Class WeChat * Author chenqionghe * @ ...
- JQ-bootstrap我的开源前端框架
因为实在不知道写啥,所以迟迟没有相关的介绍.但是必须要积累过程资产,所以还是介绍一下,不定哪天就有人用了. 首先还是介绍遇到的问题,我是做传统后台管理系统的,公司赶时髦,要用boo ...
- The 2018 ACM-ICPC Asia Qingdao Regional Contest(部分题解)
摘要: 本文是The 2018 ACM-ICPC Asia Qingdao Regional Contest(青岛现场赛)的部分解题报告,给出了出题率较高的几道题的题解,希望熟悉区域赛的题型,进而对其 ...
- SQL--server事物
事物 特点: 1.原子性:事物必须是一个自动工作的单元, 2.一致性:事物结束的时候,所有内部数据都是正确的 3.隔离性:并发多个事物时,各个事物不干涉内部数据,处理的都是另外一个事物处理之前或之后的 ...
- 利用谷歌网站的翻译网站,实现谷歌翻译api
代码是之前网上找到的,地址为:http://www.crifan.com/teach_you_how_to_find_free_google_translate_api/ 原先的代码有不足,如果翻译里 ...
- SQL 用于各种数据库的数据类型(转载) sqlserver 数据类型 取值范围 长度
SQL 用于各种数据库的数据类型 来源 http://www.runoob.com/sql/sql-datatypes.html 面向数据库编程中,数据类型的取值范围.长度,可能是需要经常查看的 ...