sql 键查找 索引查找

抽象 (Abstract)

It is common assumption that an Index Seek operation in a query plan is optimal when returning a low number of output rows. In a scenario involving residual predicates, an Index Seek operation could be reading a lot more rows than it needs into the memory, then each row is evaluated and discarded in memory based on the residual predicate and returns low number of output rows.

通常假设在返回少量输出行时查询计划中的索引查找操作是最佳的。 在涉及残留谓词的场景中,索引查找操作可能会向内存中读取比其所需数量更多的行,然后,根据残留谓词对每一行进行评估并丢弃到内存中,并返回少量的输出行。

This article will explain the concept and the impact of Residual Predicates in a SQL Server Index Seek operation.

本文将解释SQL Server索引查找操作中残留谓词的概念和影响。

索引搜寻操作 (Index Seek Operation)

SQL Server accesses a table or an index via the mean of a lookup, scan or a seek operation. In an index seek operation, a Seek Predicate is when SQL Server is able to get the exact filtered result. In the case of an index seek on multi-column, SQL Server may introduce a Predicate in the Index Seek operation. This Predicate is often referred as residual predicate because SQL Server performs additional filtering on the resultset from the index seek operation.

SQL Server通过查找,扫描或查找操作的方式访问表或索引。 在索引查找操作中,“查找谓词”是指SQL Server能够获得准确的筛选结果。 在多列上进行索引查找的情况下,SQL Server可能在索引查找操作中引入谓词。 该谓词通常称为残差谓词,因为SQL Server对来自索引查找操作的结果集执行附加筛选。

To understand the behaviour of residual predicate in SQL Server, we will walk-through two scenarios

若要了解残留谓词在SQL Server中的行为,我们将演练两种情况

  • Index Seek 索引搜寻
  • Index Seek with Residual Predicate 带有谓词的索引搜索

The scenarios will utilize WideWorldImportersDW database on SQL Server 2016 Developer Edition Service Pack 1.

这些方案将利用SQL Server 2016 Developer Edition Service Pack 1上的WideWorldImportersDW数据库。

索引搜寻谓词 (Index Seek Predicate)

This scenario will walkthrough a common index seek predicate operation. First, we will create a non-clustered index on [Fact].[Order] table as below

此场景将演练通用索引查找谓词操作。 首先,我们将在[Fact]。[Order]表上创建一个非聚集索引,如下所示


USE WideWorldImportersDW
GO
CREATE NONCLUSTERED INDEX IX_SQLShack_StockItemKey ON [Fact].[Order] ([Salesperson Key])
INCLUDE ([Stock Item Key])

We will now execute the query below and look at the query plan and the I/O statistics

现在,我们将在下面执行查询,并查看查询计划和I / O统计信息

A total of 2,585 rows returned and the logical reads incurred are 22 reads.

总共返回了2585行,并且发生的逻辑读取是22次读取。

We need to pay attention to a new SQL Server XML attribute Number of Rows Read in the query plan which was introduced in the SQL Server Service Pack level listed below to diagnose query plan which involved predicate pushdown.

我们需要注意查询计划中新SQL Server XML属性“已读取行数” ,该属性在下面列出SQL Server Service Pack级别中引入,用于诊断涉及谓词下推的查询计划。

  • SQL Server 2012 Service Pack 3 SQL Server 2012 Service Pack 3
  • SQL Server 2014 Service Pack 2 SQL Server 2014 Service Pack 2
  • SQL Server 2016 Service Pack 1 SQL Server 2016 Service Pack 1

The XML attribute will not appear your query plan if the service pack level is lower than the list above or on a SQL Server version lower than SQL Server 2012.

如果Service Pack级别低于上面的列表或SQL Server版本低于SQL Server 2012,则XML属性将不会出现在您的查询计划中。

Estimated Number of Rows to be Read is another new XML attributed introduced in SQL Server 2016 Service Pack 1. But to diagnose query plan with residual predicate, this article will focus on the XML attribute Number of Rows Read.

预计要读取的行数是SQL Server 2016 Service Pack 1中引入的另一个新XML属性。但是,为了诊断带有残留谓词的查询计划,本文将重点介绍XML属性“已读取行数”

XML attribute Description
Number of Rows Read (**New) Number of actual rows accessed by SQL Server. In this example, SQL Server read 2,585 rows
Actual Number of Rows Number of rows output from the index seek operation. In the example, all the 2,585 rows satisfies the condition in the index seek
XML属性 描述
读取的行数(**新) SQL Server访问的实际行数。 在此的示例SQL Server读取2,585行
实际行数 索引查找操作输出的行数。 在该示例中,所有2,585行都满足索引查找中的条件

In this scenario where there is no residual predicate, the Index Seek operator properties shows that SQL Server reads and outputs the same number of rows. It means that SQL Server only reads the rows that it requires and spool the rows to the next operator.

在没有剩余谓词的这种情况下,“索引查找”运算符属性显示SQL Server读取并输出相同数量的行。 这意味着SQL Server仅读取其所需的行,并将其后台处理到下一个运算符。

带有谓词的索引搜索 (Index Seek with Residual Predicate)

The first scenario is an Index Seek with Seek Predicates. We will now modify the query slightly and introduce a second predicate on column [Stock Item Key] into the query. Since this column is an included column in the index definition IX_SQLShack_StockItemKey, SQL Server would still be able to perform an index seek on the same non-clustered index.

第一种情况是带有搜索谓词的索引搜索。 现在,我们将稍微修改查询,并在查询中的[Stock Item Key]列上引入第二个谓词。 由于此列是索引定义IX_SQLShack_StockItemKey中的包含列,因此SQL Server仍将能够对同一非聚集索引执行索引查找。

The query plan looks the same as before and the logical reads incurred are still 22 reads. The query returns 13 rows, but the statistics I/O reads is same as if 2,585 rows were read.

查询计划看起来与以前相同,并且发生的逻辑读取仍然是22个读取。 该查询返回13行,但是统计信息I / O读取与读取2585行相同。

Looking at the Index Seek operator properties, SQL Server read 2,585 rows (indicated by the new XML attribute Actual Number of Rows), then performs a filtering based on the Predicate ([Stock Item Key] = 173) and the actual rows spooled to the next operator is only 13 rows (indicated by the Actual Number of Rows).

查看“索引查找”运算符属性,SQL Server读取2,585行(由新的XML属性“ 实际行数”表示 ),然后根据谓词([Stock Item Key] = 173)和后台处理的实际行执行筛选。 next运算符只有13行(由实际行数指示)。

残留谓词下推的说明 (Explanation on Residual Predicate Pushdown)

We can learn a bit more about residual predicate behaviour using an undocumented trace flag 9130. Before SQL Server introduced Number of Rows Read attribute, trace flag 9130 is the workaround to troubleshoot queries which contains residual predicate.

我们可以使用未记录的跟踪标志9130了解有关残余谓词行为的更多信息。在SQL Server引入“读取的行数”属性之前,跟踪标志9130是解决包含残余谓词的查询的变通方法。

We will use the trace flag as a query option as below.

如下所示,我们将使用跟踪标志作为查询选项。

What the trace flag shows us is that SQL Server first reads all the 2,585 rows into memory, then evaluate each row and discard rows which do not satisfy the condition in the Filter operator based on the second predicate. This explains why the same I/O reads were incurred by both queries in the two scenarios.

跟踪标志向我们显示的是SQL Server首先将所有2,585行读取到内存中,然后评估第二行并基于第二个谓词丢弃不满足Filter运算符中条件的行。 这就解释了为什么在两种情况下两个查询都会产生相同的I / O读取。

残留谓词对性能的影响 (Performance Impact due to Residual Predicate)

We now move on to an example to compare the query performance of an Index Seek with and without residual.

现在我们来看一个示例,比较带有和不带有残差的索引搜索的查询性能。

We will use the query below as an example. One of the reasons to use query hint LOOP JOIN is the ease in demonstrating a scenario where residual predicate can really hurt query performance.

我们将使用以下查询作为示例。 使用查询提示LOOP JOIN的原因之一是很容易地说明残余谓词确实会损害查询性能的情况。

The query incurred 127,851 logical reads on [Fact].[Order] table and took almost 3 seconds to complete execution. The Index Seek properties indicate that SQL Server read over 19 million rows into memory, but really only requires 92,781 rows.

该查询对[Fact]。[Order]表进行了127,851次逻辑读取,并花费了近3秒钟来完成执行。 索引查找属性指示SQL Server将超过1900万行读入内存,但实际上仅需要92,781行。

We will now create another index definition and forces the query to use this index instead.

现在,我们将创建另一个索引定义,并强制查询使用该索引。

This query incurred 40,332 logical reads on [Fact].[Order] table and took less than half second to complete execution. This query is 6 times faster without residual. In this scenario, SQL Server pushes the filter down to the table access operator itself and only read exactly 98,781 rows that it needs.

该查询在[Fact]。[Order]表上进行了40,332个逻辑读取,并且不到半秒即可完成执行。 此查询速度快了6倍,没有残留。 在这种情况下,SQL Server将筛选器下推到表访问运算符本身,并且仅准确读取它需要的98,781行。

摘要 (Summary)

Predicate pushdown is important because you would want SQL Server to filter the results as early as possible in the query plan. The more rows that SQL Server operator has to access, the longer the operation will take.

谓词下推很重要,因为您希望SQL Server在查询计划中尽早筛选结果。 SQL Server操作员必须访问的行越多,操作所需的时间就越长。

A Residual predicate scenario can occur in many forms and scenarios other than the examples in this article. Understanding the behaviour of residual predicates will allow better analysis in relation to performance tuning and troubleshooting.

除本文中的示例以外,残留谓词方案可以多种形式出现。 了解残差谓词的行为将允许在性能调整和故障排除方面进行更好的分析。

In addition, SQL Server now has introduced new XML attributes to better diagnose query plans that involve residual predicate pushdown.

此外,SQL Server现在引入了新的XML属性,以更好地诊断涉及残留谓词下推的查询计划。

翻译自: https://www.sqlshack.com/the-impact-of-residual-predicates-in-a-sql-server-index-seek-operation/

sql 键查找 索引查找

sql 键查找 索引查找_残留谓词对SQL Server索引查找操作的影响相关推荐

  1. sql重命名数据库_为什么要为SQL单元测试巧妙地命名数据库对象

    sql重命名数据库 This article is focussed on clever database object naming from both development and SQL un ...

  2. sql备份恢复数据库_使用DBATools通过SQL恢复数据库操作验证备份

    sql备份恢复数据库 In this article, we will explore database backup validation by with SQL restore database ...

  3. sql如何处理null值_如何正确处理SQL中的NULL值

    sql如何处理null值 前言 (Preface) A friend who has recently started learning SQL asked me about NULL values ...

  4. sql查询 关联帖子_从零学会sql,复杂查询

    一.视图,表中存放的是实际数据,视图中存放的是SQL查询语句,使用视图时,会运行视图里的sql查询语句创建出一张临时表,格式是create view 视图名称(<视图列表1>,<视图 ...

  5. 学习sql注入:猜测数据库_面向数据科学家SQL:学习简单方法

    学习sql注入:猜测数据库 We don't pick a hammer and look for nails - that would be an unusual way of solving pr ...

  6. sql 存储过程 盲注入_一次非常规 SQL 注入(informixsql)的利用过程

    介绍 一个客户正在寻找升级他们的思科 UCM 软件,并希望保证他们的实现是安全配置的.在评估期间,我们在 Cisco UCM 管理员门户中发现了一个经过身份验证的 SQL 注入问题.在大多数情况下,可 ...

  7. oracle 导入sql文件 汉字乱码_将现有的sql脚本导入 Oracle 数据库,中文乱码问题...

    将现有的sql 脚本导入 Oracle数据库 比如 在windows 系统下,可以写一个 bat 来实现直接导入 如:bat 中的内容如下,logs.log 将会记录执行日志 sqlplus user ...

  8. sql 整改措施 注入_记一次Sql注入 解决方案

    老大反馈代码里面存在sql注入,这个漏洞会导致系统遭受攻击,定位到对应的代码,如下图所示 image like 进行了一个字符串拼接,正常的情况下,前端传一个 cxk 过来,那么执行的sql就是 se ...

  9. java得到sql语句表名_使用fdb-sql-parser替换SQL语句中的表名

    导语 因为项目中要做跨数据源的数据分析功能,所以使用Presto这个开源框架.但是使用Presto的时候需要指定当前表所在的数据库类型和数据库名,所以需要对SQL语句中的表名进行捕获和替换. 一.探索 ...

最新文章

  1. Cocos Creator中按钮组件数组的使用
  2. Linux_相关命令(学习,备忘)
  3. iscsi介绍及iscsi target配置
  4. SQL Server 常用近百条SQL语句(收藏版)
  5. IHttpHandler给图片加水印
  6. “高校”行业智能运维解决方案解析(含落地实践)
  7. 广州计算机公办学校有哪些,广州各区小学对口中学列表,小学对口哪些初中?这里有名单大全...
  8. 基于Android的防疫信息管理系统源码【包调试运行】
  9. 教你如何测试U盘读写速度?
  10. MII/MDIO接口详解
  11. python UI自动化自动关闭浏览器学习记录
  12. python 安装第三方包-安装失败(pycharm/ anaconda navigator)
  13. 达观数据:文字的起源与文本挖掘的前世今生
  14. C#List子类转List父类或者Obj对象转List
  15. Cocos Creator 3.2 中实现2D地图3D人物45度角RPG游戏效果笔记(摄像机设置方案)
  16. 毛泽东思想和中国特色社会主义理论体系概论
  17. 关于CG,CV,DIP
  18. C语言查找奥运五环色的位置
  19. 4、cloudsim仿真步骤
  20. 开源办公OA平台教程:如何修改O2OA配置连接本地部署的OnlyOffice Docs Server服务器?

热门文章

  1. 网络编程学习2-套接字编程简介
  2. NOI2015 荷马史诗
  3. 前端(jQuery)(10)-- jQuery标签切换
  4. iOS开发错误处理技巧,PCH文件的使用,自定义NSNotification消息以及设置监听者(以Core Data处理数据时的错误为例)...
  5. apk反编译、smali修改、回编译笔记
  6. 在Android中通过导入静态数据库来提高应用第一次的启动速度
  7. table设置width无效
  8. WebSocket使用80端口的方法
  9. php apache 配置后不能正常显示html文件的解决方法
  10. Go语言---结构体