首页 > 数据库 >SQLSERVER - 性能优化

SQLSERVER - 性能优化

时间:2024-01-16 23:57:02浏览次数:34  
标签:排序 性能 SQLSERVER 查询 运算符 索引 联接 优化 聚集

行存储和列存储

行存储

场景:数据维护,数据检索

列存储

场景:数据分析

索引的了解

聚集索引

  • 聚集索引中,叶节点包含基础表的数据页。

  • 数据链内的页和行将按聚集索引键值进行排序。

  • 主键通常是聚集索引,但可以不是聚集索引。

非聚集索引

  • 基础表的数据行不会根据其非聚集键按顺序排序和存储。

  • 非聚集索引的叶级别是由索引页而不是由数据页组成。

  • 非聚集索引的叶级别的索引页包含键列以及包含列。

SQL Server查找数据记录的几种方式:

1.Table Scan--表扫描(最慢),对表记录逐行进行检查,对于没有索引或者查询条件不走索引时会进行全表扫描;

2.Clustered Index Scan--聚集索引扫描(较慢),按聚集索引对记录逐行进行检查,对有主键/聚集索引的表进行无条件查找或者使用主键/聚集索引过滤;

3.Index Scan--索引扫描(普通),根据索引滤出部分数据在进行逐行检查,;

4.Index Seek--索引查找(较快),根据索引定位记录所在位置再取出记录,建立非聚集索引并把其他显示列加入索引中;

5.Clustered Index Seek--聚集索引查找(最快),直接根据聚集索引获取记录,建立非聚集索引并把其他显示列加入索引中并把聚集索引列当作条件;

6.Key Lookup--书签查找:通过非聚集索引找到所求的行,但这个索引并不包含显示的列,因此还要额外去基本表中找到这些列,所以要进行键查找,如果基本表在堆中则Key Lookup会变成RID查找。

7.RID--书签查找:同上

如果有些SQL执行很慢,可以用执行计划看一下是否包含太多“扫描”操作,可以考虑为这些字段建立索引,建立索引切记不要再经常有更新操作的字段上建立,每次更新数据和插入数据都会导致重建索引的操作,会增加索引的维护成本。

Showplan 运算符 说明
表扫描运算符图标 Table Scan Table Scan 运算符从查询执行计划的 Argument 列所指定的表中检索所有行。 如果 WHERE:() 谓词出现在 Argument 列中,则仅返回满足此谓词的那些行。
Table Scan 既是一个逻辑运算符,也是一个物理运算符。
表扫描运算符图标 Clustered Index Scan Clustered Index Scan 运算符会扫描查询执行计划的 Argument 列中指定的聚集索引。 存在可选 WHERE:() 谓词时,则只返回满足该谓词的那些行。
如果 Argument 列包含 ORDERED 子句,则表示查询处理器已请求按聚集索引排列行的顺序返回行输出。
如果没有 ORDERED 子句,存储引擎将以最佳方式扫描索引,而无需对输出进行排序。 Clustered Index Scan 既是一个逻辑运算符,也是一个物理运算符。
表扫描运算符图标 Index Scan Index Scan 运算符从 Argument 列中指定的非聚集索引中检索所有行。 如果可选的 WHERE:() 谓词出现在 Argument 列中,则仅返回满足此谓词的那些行。
Index Scan 既是一个逻辑运算符,也是一个物理运算符。
表扫描运算符图标 Index Seek Index Seek 运算符利用索引的查找功能从非聚集索引中检索行。 Argument 列包含所使用的非聚集索引的名称。 它还包括 SEEK:() 谓词。
存储引擎仅使用索引来处理满足 SEEK:() 谓词的行。 它可能还包含一个 WHERE:() 谓词,其中存储引擎对满足 SEEK:() 谓词的所有行进行计算(不使用索引来完成)。
如果 Argument 列包含 ORDERED 子句,则表示查询处理器已决定必须按非聚集索引排序行的顺序返回行。
如果没有 ORDERED 子句,则存储引擎将以最佳方式(不保证对输出排序)搜索索引。 如果让输出保持其顺序,则效率可能低于生成非排序输出。
Index Seek 既是一个逻辑运算符,也是一个物理运算符。
表扫描运算符图标 Clustered Index Seek Clustered Index Seek 运算符可以利用索引的查找功能从聚集索引中检索行。 Argument 列包含所使用的聚集索引名称和 SEEK:() 谓词。
存储引擎仅使用索引来处理满足此 SEEK:() 谓词的行。它还包括 WHERE:() 谓词,其中存储引擎对满足 SEEK:() 谓词的所有行进行计算,
但此操作是可选的,并且不使用索引来完成此过程。



如果 Argument 列包含 ORDERED 子句,则表示查询处理器已决定必须按聚集索引排序行的顺序返回行。
如果没有 ORDERED 子句,存储引擎将以最佳方式搜索索引,而不对输出进行必要的排序。 若允许输出保持顺序,则效率可能比生成非排序输出的效率低。
出现关键字 LOOKUP 时,将执行书签查找。 在 SQL Server 2008 (10.0.x) 及更高版本中,键查找运算符提供书签查找功能。
Clustered Index Seek 既是一个逻辑运算符,也是一个物理运算符。
表扫描运算符图标 Key Lookup Key Lookup 运算符是在具有聚集索引的表上进行的书签查找。 Argument 列包含聚集索引的名称和用来在聚集索引中查找行的聚集键。
Key Lookup 通常带有 Nested Loops 运算符。 如果 Argument 列中出现 WITH PREFETCH 子句,
则表示查询处理器已决定在聚集索引中查找书签时将使用异步预提取(预读)作为最佳选择。

在查询计划中使用 Key Lookup 运算符表明该查询可能会从性能优化中获益。 例如,添加涵盖索引可能会提高查询性能。
表扫描运算符图标 RID Lookup RID Lookup 是使用提供的行标识符 (RID) 在堆上进行的书签查找。 Argument 列包含用于查找表中的行的书签标签和从中查找行的表的名称。
RID Lookup 通常带有 NESTED LOOP JOIN。 RID Lookup 是一个物理运算符。 有关书签查找的详细信息,请参阅 MSDN SQL Server 博客中的Bookmark Lookup(书签查找)。

数据 JOIN方式

在SQL Server中,每个join命令,都会在内部执行时采用这几种更具体的方式来运行:

  1. Nested Loops join:如果一个联接输入很小,而另一个联接输入很大而且已在其联接列上创建了索引, 则索引 Nested Loops 连接是最快的联接操作,因为它们需要的 I/O 和比较都最少。嵌套循环联接也称为“嵌套迭代”,它将一个联接输入用作外部输入表(显示为图形执行计划中的顶端输入),将另一个联接输入用作内部(底端)输入表。外部循环逐行处理外部输入表。内部循环会针对每个外部行执行,在内部输入表中搜索匹配行。最简单的情况是,搜索时扫描整个表或索引;这称为“单纯嵌套循环联接”。如果搜索时使用索引,则称为“索引嵌套循环联接”。如果将索引生成为查询计划的一部分(并在查询完成后立即将索引破坏),则称为“临时索引嵌套循环联接”。

如果外部输入较小而内部输入较大且预先创建了索引,则嵌套循环联接尤其有效。在小事务中(只影响较少数据的事务),索引嵌套循环联接优于合并联接和哈希联接,但在大型查询中,嵌套循环联接通常不是最佳选择。

  1. Merge Join:如果两个联接输入并不小但已在二者联接列上排序(例如,如果它们是通过扫描已排序的索引获得的),则合并联接是最快的联接操作。如果两个联接输入都很大,而且这两个输入的大小差不多,则预先排序的合并联接提供的性能与哈希联接相近。但是,如果这两个输入的大小相差很大,则哈希联接操作通常快得多。合并联接要求两个输入都在合并列上排序,而合并列由联接谓词的等效 (ON) 子句定义。通常,查询优化器扫描索引(如果在适当的一组列上存在索引),或在合并联接的下面放一个排序运算符。在极少数情况下,虽然可能有多个等效子句,但只用其中一些可用的等效子句获得合并列。

  2. Hash Join:哈希联接可以有效处理未排序的大型非索引输入。它们对复杂查询的中间结果很有用,因为:①.中间结果未经索引(除非已经显式保存到磁盘上然后创建索引),而且通常不为查询计划中的下一个操作进行适当的排序。②.查询优化器只估计中间结果的大小。由于对于复杂查询,估计可能有很大的误差,因此如果中间结果比预期的大得多,则处理中间结果的算法不仅必须有效而且必须适度弱化。哈希联接可以减少使用非规范化。非规范化一般通过减少联接操作获得更好的性能,尽管这样做有冗余之险(如不一致的更新)。哈希联接则减少使用非规范化的需要。哈希联接使垂直分区(用单独的文件或索引代表单个表中的几组列)得以成为物理数据库设计的可行选项。

Showplan 运算符 说明
表扫描运算符图标 合并联接
Merge Join
Merge Join 运算符执行内部联接、左外部联接、左半部联接、左反半部联接、右外部联接、右半部联接、右反半部联接和联合逻辑运算。

在 Argument 列中,如果操作执行一对多联接,则 Merge Join 运算符将包含 MERGE:() 谓词;如果操作执行多对多联接,则该运算符将包含 MANY-TO-MANY MERGE:() 谓词。
Argument 列还包含一个用于执行操作的列的列表,该列表以逗号分隔。 Merge Join 运算符要求在各自的列上对两个输入进行排序,这可以通过在查询计划中插入显式排序操作来实现。
如果不需要显式排序(例如,如果数据库内有合适的 B 树索引或可以对多个操作(如合并联接和对汇总分组)使用排序顺序),则合并联接尤其有效。
Merge Join 是一个物理运算符。 有关详细信息,请参阅理解合并联接
表扫描运算符图标 Nested Loops Nested Loops 运算符执行内部联接、左外部联接、左半部联接和左反半部联接逻辑运算。 嵌套循环联接通常使用索引,针对外部表的每一行在内部表中执行搜索。
查询处理器根据预计的开销来决定是否对外部输入进行排序,以改进内部输入索引上的搜索定位。 将基于所执行的逻辑操作返回所有满足 Argument 列中的(可选)谓词的行。
如果 OPTIMIZED 特性设置为“True”,则表示使用了优化的嵌套循环(或批处理排序)。 Nested Loops 是一个物理运算符。 有关详细信息,请参阅了解嵌套循环联接
Hash join 哈希联接可以有效处理未排序的大型非索引输入。 它们对复杂查询的中间结果很有用,因为:

中间结果未经索引(除非已经显式保存到磁盘上然后创建索引),而且通常不为查询计划中的下一个操作进行适当的排序。
查询优化器只估计中间结果的大小。 由于对于复杂查询,估计可能有很大的误差,因此如果中间结果比预期的大得多,则处理中间结果的算法不仅必须有效而且必须适度弱化。
哈希联接可以减少使用非规范化。 非规范化一般通过减少联接操作获得更好的性能,尽管这样做有冗余之险(如不一致的更新)。
哈希联接则减少使用非规范化的需要。 哈希联接使垂直分区(用单独的文件或索引代表单个表中的几组列)得以成为物理数据库设计的可行选项。

哈希联接有两种输入:生成输入和探测输入。 查询优化器指派这些角色,使两个输入中较小的那个作为生成输入。

哈希联接用于多种设置匹配操作:内部联接;左外部联接、右外部联接和完全外部联接;左半联接和右半联接;交集;并集和差异。
此外,哈希联接的某种变形可以进行重复删除和分组,例如 SUM(salary) GROUP BY department。 这些修改对生成和探测角色只使用一个输入。

参考:

SQLServer查询语句执行计划 - 吴淞 - 博客园

显示计划逻辑运算符和物理运算符参考 - SQL Server | Microsoft Learn

标签:排序,性能,SQLSERVER,查询,运算符,索引,联接,优化,聚集
From: https://www.cnblogs.com/tangge/p/17968884

相关文章

  • ElasticSearch中_source、store_fields、doc_values性能比较【转载】
    原文地址请点击在这篇文章中,我想从性能的角度探讨ElasticSearch为我们存储了哪些字段,以及在查询检索时这些字段如何工作。实际上,ElasticSearch和Solr的底层库Lucene提供了两种存储和检索字段的方式:store_fields和doc_values。此外,ElasticSearch默认提供了 _source 字段,这是在......
  • 性能篇:List集合遍历元素用哪种方式更快?
    嗨大家好,我是小米!今天给大家分享一篇关于Java集合框架性能的文章,话题是:“如果让你使用for循环以及迭代循环遍历一个ArrayList,你会使用哪种方式呢?原因是什么?LinkedList呢?”废话不多说,让我们直入主题!ArrayList的get元素源码介绍ArrayList,作为Java集合框架中的一个重要类,是基于数组......
  • 智慧工单,倒逼服务全链条优化
    作为售后服务的核心部分,工单管理模块占据了重要地位,而工单管理是否可以取得数字化成功,也在一定程度上决定了售后服务的数字化是否成功。那么如果想建立智慧工单,应该从哪些方面进行衡量和设计考虑?一起来看看作者的总结分析。我在前一篇文章《B2C基础服务创新》中介绍了售后服务主要......
  • 【快速阅读二】从OpenCv的代码中扣取泊松融合算子(Poisson Image Editing)并稍作优化
    泊松融合我自己写的第一版程序大概是2016年在某个小房间里折腾出来的,当时是用的迭代的方式,记得似乎效果不怎么样,没有达到论文的效果。前段时间又有网友问我有没有这方面的程序,我说Opencv已经有了,可以直接使用,他说opencv的框架太大,不想为了一个功能的需求而背上这么一座大山,看......
  • 优化您的服务请求,增强用户体验和服务交付
    您的服务请求模板是否像一个复杂的迷宫,给您的团队带来延误和困惑?您的技术人员是否厌倦了为了解最终用户的需求而与他们来回奔波?强大且可定制的请求模板可能正是您所需要的!  服务交付团队(尤其是IT)的用户可以通过各种渠道(如电子邮件、电话、聊天和步入式)获得多种服务。缺乏确......
  • OLAP引擎也能实现高性能向量检索,据说QPS高于milvus!
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群随着LLM技术应用及落地,数据库需要提高向量分析以及AI支持能力,向量数据库及向量检索等能力“异军突起”,迎来业界持续不断关注。简单来说,向量检索技术以及向量数据库能为LLM提供外置的记忆单......
  • OLAP引擎也能实现高性能向量检索,据说QPS高于milvus!
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群随着LLM技术应用及落地,数据库需要提高向量分析以及AI支持能力,向量数据库及向量检索等能力“异军突起”,迎来业界持续不断关注。简单来说,向量检索技术以及向量数据库能为LLM提供外置的记忆单......
  • sqlserver查询最近失败的任务
    selectjob_id,step_name,message,cast((cast(LEFT(run_date,4)ASVARCHAR)+'-'+SUBSTRING(cast(run_dateASVARCHAR),5,2)+'-'+cast(RIGHT(run_date,2)ASVARCHAR))+'......
  • 屎山代码风格指南(避免被优化&&避免被接盘)
    欢迎补充!!!序言良好的代码结构:Bad......
  • CDN静态资源加速&Lighthouse性能监测
    本文主要介绍了cdn加速在项目中的实现,以及使用Lighthouse对前端性能指标进行监测打分。Lighthouse简介Lighthouse是谷歌开发并开源的web性能测试工具,用于改进网络应用的质量,可以将其作为一个Chrome扩展程序运行,或从命令行运行。只需要为其提供一个需要审查的地址,Lighthouse就会......