【一些网课后的笔记与后续学习的思考】

平时我们觉得查数据很慢,这个慢是什么意思?
就是在现有资源达到最大吞吐量的前提下,系统不能满足合理的数据请求的一些表现。

一、调优时,可以从以下五点考虑

① 最小化SQL相应时间
② 合理地增加吞吐量
③ 减少网络延迟
④ 优化IO
⑤ 减少最小化

二、调优要达到的目标

使系统能有协调、平衡地运作,合理地响应外部及内部请求,实现资源利用的最大化。

三、性能调优的误区

1、增加硬件就能缓解性能问题

增加硬件或许会让系统性能更好,但没有解决真正的问题所在

2、只要数据库性能好就没问题

不要把很多本该在应用层实现的逻辑放到数据库实现,以此希望优化数据库就能解决性能问题

3、任何的数据库性能问题都可以通过索引解决

性能问题的解决思路:
检查日志,发现问题所在——优化SQL语句或修改表结构——最后才是考虑建立索引

4、编码过于激进或极端

任何功能都有自己的场景,要根据自己的企业形式、开发模式和技术栈去综合考虑,切忌一刀切(比如:要么全部使用存储过程实现功能,要么完全不允许使用存储过程)

四、影响性能的常见因素:

1、数据库结构的设计

①了解业务、满足业务,性能只是业务之外的附属属性
②优先考虑第三范式设计(字段冗余可以避免过多的表关联,但是字段冗余会让维护成本提升。这时就需要对维护成本和过
③多关联查询影响性能进行权衡)
④表关联要尽可能地少
⑤坚持最小原则:使用尽可能小的字段长度
⑥在适当的地方使用约束:但是,安全方面还是最重要的,千万不要为了性能而放弃对安全的追求!因为我们并不需要极致的性能,而是性能在一定范围内可以承受就可以了。

2、事务和隔离的级别

3、T-SQL的编写

数据库性能的优化,基本都是针对SQL语句的优化。编写健壮的T-SQL语句,让我们的代码更稳定,更高效地执行
①编写语句前,要完全了解业务的需求,知道表的用途和用法,明确查询目的
②只查询需要的字段,避免返回所有字段(select * from )
③限定好查询地结果集(select top 100 …)
④使用有效的索引,确保业务需要用到的过滤字段能使用索引,是否有必要在字段上添加索引
(当需要对数据进行过滤时,应当优先考虑使用索引字段。要是有多个索引字段可供选择,优先选择筛选率较高、重复率较低的索引字段作为过滤条件)
⑤不要对有索引的字段使用计算、函数等运算符,因为会导致查询优化器无法使用索引进行数据的检索,从而导致表触发扫描操作
⑥order by字句的性能,取决于参与排序操作的数据量大小。
(排序操作会在数据筛选完以后,对筛选出的结果集进行排序。因此对需要进行排序的操作,应将排序的操作控制在结果集和数据量都尽量小的查询中,避免不必要的CPU消耗。不然,当排序操作超过可以分配的内存大小时,就会把排序的中间数据放在TempDb,增加I/O操作,导致性能大大下降)
⑦尽量使用简单的SQL语句来实现业务功能
简单的SQL语句:只关联2-4个表、单表查询、只有2-3个过滤条件,并且有一个过滤条件明确可以使用索引查找操作

4、硬件资源

五、执行计划的分析

在SQL优化中,都是以SQL语句的执行计划中的开销去判断最优的语句。

SQL语句的处理流程如图示:

1、T-SQL语句

没啥好说的,就是你的SQL语句

2、语法分析

编译语法,检验语句和语法是否合规、正确,然后把T-SQL语句转化为逻辑查询树(树里包含各种逻辑代数运算:inner join…)

3、绑定

把逻辑树的节点与数据库的实际对象(比如你要查询的表)进行绑定。检验所有查询引用的对象是否都在数据库中。检验完成通过,就把逻辑树转换为绑定树,并加载各种元数据(表里相关的约束、索引…)

4、优化

使用绑定树,通过优化产生一个预估的执行计划。SQL优化器尽可能寻找最优方案(随着SQL语句的表关联和过滤条件的复杂度,方案的选择会越多,所以有可能会找到不适合的方案)
查询优化器只能基于成本选择出成本最低的一个执行计划。成本的评估和优化过程,需要大量的资源,在选择合适的计划上,SQL设置了一些阙值,以某个阙值为基准来评估优化的成本和执行计划的代价。

4.1简化

对查询进行简化,移除一些无用的条件。

4.2普通计划搜索

4.3更新统计信息

4.4基于开销的优化

真正的优化阶段,CBD阶段,分三个阶段
阶段0:分析出一些执行计划,成本小于SQLServer内定的阙值的话,选择当前这个阶段的执行计划,成本大于SQLServer内定的阙值的话进入阶段1

阶段1:快速计划,没有合适的执行计划。判断是否可以使用并行操作,当并行的执行计划成本小于串行的执行计划成本,进入阶段2

阶段2:完全优化。最综合、最全面的分析,对所有可用的优化进行全盘分析,最终选择成本最低的,退出优化。

当你的表关联少于三张,是不会进入【基于开销的优化】这个节点的,因为方案只有一个,不会进到优化阶段,优化阶段不会有开销。而当你的SQL语句越复杂,查询优化器就越消耗成本和查询时间。

5、执行

语句的执行计划中,每个运算符都有自己的开销,执行计划运算符的详细信息和各种指标如下:

  • Estimated Number of Rows 预估扫描影响的行数。
  • Estimated row size 操作符生成的行的估计大小(字节)。
  • Estimated Data Size 预估影响的数据的大小。

6、返回结果

SQL语句执行后的输出结果

7、执行计划展现方式

执行计划可以以:图像方式、文本方式和XML方式进行展现来分析。

7.1、图像方式

如果T-SQL语句过于复杂,会产生较大的流程图像

7.2、文本方式

  • SET SHOWPLAN_TEXT ON(只开启执行计划,不包括详细的评估值)

要分步执行每一个语句
文本方式展示执行计划,执行SQL语句,关闭文本展示方式

  • SET SHOWPLAN_ALL ON (开启所有的执行计划明细,包括各个属性的评估值 )

7.3、XML方式

XML方式提供的信息是最为全面的

六、执行计划中不同的运算符

执行计划里组成的单元之一,用来完成某个特定的任务。每个运算符都实现一个单独的基本操作,比如:表扫描、索引扫描、索引查找、键查找、RID查找…

1、阻塞运算符和非阻塞运算符

阻断和非阻断的区别就是:运算符是否在输入数据的时候能够直接输出结果数据

  • 阻断
    一个运算符所产生的输出结果需要等待所有的数据输入
    比如select count(*) from user_info,要等待所有的数据行输入才能 count(计算)出行数

  • 非阻断
    一个运算符在消耗输入行的同时生成输出行

要尽量的使用非阻断式操作来代替阻断式操作,这样才能更好的提高响应时间

2、逻辑运算符和物理运算符

2.1、逻辑运算符

逻辑运算符和比较运算符一样,都是返回 true 或 false 值的布尔数据类型
AND、OR、NOT、IN、EXISTS、LIKE、BETWEEN…

2.2、物理运算符

每个物理运算符都是一个执行某项操作的对象或例程。
SQL Server默认支持三种物理连接运算符:嵌套循环连接、合并连接以及哈希连接。

3、数据访问运算符(扫描、查找)

根据表类型(堆表、聚集索引表)不同,数据访问运算符也不同

3.1、扫描运算符:表扫描、聚集索引扫描、非聚集索引扫描

  • 表扫描(Table Scan)
    无任何条件地对整张表进行全表扫描
--举例:user_info_no_key表中,无主键(既无聚集索引)
select  *
from user_info_no_key

  • 聚集索引扫描(Clustered Index Scan)
    表中的所有数据行都存在于聚集索引的业节点中。相当于将整个表中地数据都取出来。
--举例:user_info表中,自增的id字段作为主键(既有聚集索引)
select  *
from user_info

  • 非聚集索引扫描(Index Scan NoClustered )
    发生在查询的数据都包含在已经定义好的索引中,就不需要扫描全表,只需将索引中的数据取出即可。(亦称为覆盖索引)
 --举例:user_info表中,自增的id字段作为主键,对user_id,user_phone都建立了非聚集索引,查询的所有字段都定义有索引
select  user_ids,user_phone
from user_info

  • 关于扫描
    数据库中,一旦出现扫描操作(Scan),就会有性能问题。因为扫描操作不仅需要等待大量的IO,还需要消耗许多内存来存储相关的数据。当数据库的缓存池中剩余空间不足的时候,它就需要把数据写到内存中。这个时候,数据库就会利用利用淘汰算法将缓存中的数据进行清理,然后再继续填充数据。
    当我们频繁地出现大量数据的淘汰,那么缓存中的数据也会频繁地交替,这时候就会造成数据库操作的性能瓶颈。
    所以在开发业务系统的时候,应尽量避免大数据量的搜索。

3.2、查找运算符:聚集索引查找、非聚集索引查找、键查找(标签查找的一种)、RID(行ID查找)

  • 聚集索引查找(Clustered Index Seek)
    发生在对聚集索引字段进行where条件过滤的情况下
 --举例:user_info表中,自增的id字段作为主键,既聚集索引。对聚集索引字段进行where条件过滤
select *
from user_info
where id=1

  • 非聚集索引查找(Index Seek NoClustered )
    发生在对非聚集索引字段进行where条件过滤的情况下
 --举例:user_info表中,自增的id字段作为主键,对user_id,user_phone都建立了非聚集索引,对非聚集索引字段进行where条件过滤
select  user_ids,user_phone
from user_info
where user_phone='11111111111'

4、关联运算符(嵌套循环、合并连接、哈希连接)

4.1、嵌套循环

外部输入的每一行,都会扫描内部大数量输入,然后输出匹配的行。
即两张表通过关键字关联,然后再进行双层循环,两张表依次关联,最后通过关键字进行筛选。(其实就相当于两层for循环,输出符合条件的值)

4.2、合并连接

从两个数据集中各取一个值进行比较,如果相符,就把两行连接起来返回,如果不相符,就把小的去,一直到两个表中某一个表的行扫描结束。
(合并连接相对于嵌套循环,对大表的操作比较高效)

4.3、散列链接(哈希连接)

顶部输入的每一行生成哈希表(Hash keys build),每一行进行哈希计算,生成哈希桶。(非常消耗资源的算法)

4.4、嵌套循环、合并连接和哈希连接的应用对比

嵌套循环 合并连接 哈希连接
最佳场景 数据集相对较小,内部表的关联没有索引 数据集中等或较大,关联字段有索引且已排序或结果集已排序 数据集较大,适合数据仓库下的复杂查询
并发性 大量并发 有索引的多对多时并发性较好 不建议大并发
关联字段是否相等
是否使用额外内存 已排序下不需要
是否使用TempDb 多对多情况下需要
数据集是否需要排序
期望输入数据集要排序 外部表已排序

5、聚合运算符(流聚合、哈希聚合)

5.1、流聚合Stream Aggregate(标量聚合)

  • max()、min()、avg()、count()、sum()

Compute Scalar:计算标量的运算符
在流聚合产生的结果项数据类型为Bigint类型,而默认输出为int类型,所以增加了一个类型转换的运算符。

  • 有group by分组的语句
    当group by的字段无索引时,会出现sort(排序)节点,占用开销,一旦出现sort运算符,开销一般都是比较大的。

所以,对于流聚合的一种优化方式:
要避免sort排序的产生,就需要group by的字段在索引覆盖范围内。

5.2、哈希聚合(散列聚合)

group by的字段无索引,并且表为大数据、大规模的表
(当对无索引的字段创建索引,哈希聚合会变成流聚合)

5.3、流聚合和哈希聚合的应用对比

流聚合 哈希聚合
最佳场景 小规模且输入已排序 中大型未排序输入
是否要求输入排序
是否阻塞操纵 否,排序时可能阻塞
是否使用内存
是否使用TempDb 否,内存不足时可能会使用
  • TempDb
    SQL Server中的一个系统数据库,用于存储查询过程中产生的中间数据。
    (TempDb存储在磁盘上,所以只要用到TempDb的操作,就会影响I/O,比如sort排序和哈希连接)

6、联合运算符(union all、union)

6.1、union all:将两个数据集结果合并

6.2、union :将两个数据集合并后进行去重

一旦出现sort,就意味着资源的消耗,所以,这里可优化的地方就出来了,就是把sort排序去掉或更换。

七、结束语

就…先到这里吧,主要简单记录了一下关于SQL Server调优时要关注的一些因素,还有一些基础的运算符。
进阶的话,就是在这些基础上,如何展开实际的SQL开销分析、语句运行时的指标监测,然后进行SQL的优化和改写。
【SQL】关于SQL Server的性能优化——基础内容,记录,打板!

【SQL】关于SQL Server的性能优化——基础内容相关推荐

  1. Sql Server查询性能优化之索引篇【推荐】

    Sql Server查询性能优化之索引篇[推荐] 这篇是索引系列中比较完整的,经过整理而来的 一 索引基础知识 索引概述 1.概念 可以把索引理解为一种特殊的目录.就好比<新华字典>为了加 ...

  2. 【SQL Server】性能优化-索引

    性能优化-索引 1 索引 1.1 什么是索引 1.2 索引的存储机制 1.3 创建索引原则 1.4 如何创建索引 1.4.1 创建索引 1.4.1 删除索引 1.4.1 显示索引 1.5 索引使用次数 ...

  3. SQL Server 查询性能优化——覆盖索引(二)

    在SQL Server 查询性能优化--覆盖索引(一)  中讲了覆盖索引的一些理论. 本文将具体讲一下使用不同索引对查询性能的影响. 下面通过实例,来查看不同的索引结构,如聚集索引.非聚集索引.组合索 ...

  4. Sql Server查询性能优化之走出索引的误区

    据了解绝大多数开发人员对于索引的理解都是一知半解,局限于大多数日常工作没有机会.也什么没有必要去关心.了解索引,实在哪天某个查询太慢了找到查询条件建个索引就ok,哪天又有个查询慢了,再建立个索引就是, ...

  5. 前端性能优化基础知识--幕课网

    作为一个前端小码农,在页面样式都能实现以后,就开始考虑:同一个效果,我该用什么样的方式和代码去实现它比较规范?前两天逛幕课网发现了两门课程–<前端性能优化-基础知识认知>和<前端性能 ...

  6. 由美团技术文章整理---spark性能优化基础篇--开发调优与资源参数调优

    文章地址1:Spark性能优化指南--基础篇 - 美团技术团队 文章地址2:Spark性能优化指南--高级篇 - 美团技术团队 目录 一.关于性能优化基础篇--开发调优 1.避免创建重复RDD (1) ...

  7. SQL Server 2005 性能优化实战系列(文章索引)

    http://www.cnblogs.com/gaizai/archive/2012/01/20/2327814.html 前言 性能优化是数据库方向一个很重要的技能,这也是快速提供企业级应用性能最快 ...

  8. SQL Server 追踪Profiler,SQL Server的性能优化工具

    点击上方SQL数据库开发,关注获取SQL视频教程 SQL专栏 SQL数据库基础知识汇总 SQL数据库高级知识汇总 SQL Server Profiler是什么 SQL Server Profiler是 ...

  9. SQL Server 数据库性能优化

    对一个数据库来说,只能做到更优,不可能最优,并且根据实际需要,优化方案也是有所差异的,大概需要我们关心的有它的读取速度.存储空间.可维护性以及可扩展性等,而这些方面往往又是相互矛盾的,那么本文就着重讲 ...

最新文章

  1. python神秘的魔法函数_python进阶之魔法函数
  2. 【网络流】解题报告: luogu P2045 方格取数加强版(k取方格数)(最大费用最大流)
  3. 指纹传感器沾水便失效的原因解析
  4. Mysql 出现Got error 28 from storage engine
  5. 性能优化(7):教你正确使用css选择器
  6. 信息学奥赛一本通 1136:密码翻译 | OpenJudge NOI 1.7 09
  7. Jenkins报错Error fetching remote repo 'origin'真正解决办法
  8. hdu3094 A tree game
  9. dispatcherServlet源码分析之doDispatch
  10. qq企业邮箱创建过程
  11. ppt制作心得【转发】
  12. 【NLP】文本情感分析
  13. jar error in opening zip file
  14. 树莓派4B EC20 查看4G信号强度
  15. 卡特加特数字家庭又爆重磅合作!厦门火炬创投莅临卡特加特考察
  16. 希沃白板如何解决手机端播放课件内视频出现黑屏闪退
  17. Java SE 高级教程
  18. 基于php的学生公寓管理系统,php毕业设计学生公寓管理系统
  19. 系统安全及应用--账号安全控制
  20. 动漫网站源码设计与实现

热门文章

  1. ab 发送post请求 测试API性能
  2. cad怎样编辑标注文字?分享一个方法
  3. 各种智能跟随定位技术解剖
  4. 显卡---显卡驱动---CUDA---Cudnn
  5. 为什么苹果录屏没有声音_苹果手机自带录屏功能,打开声音录制方法
  6. 免费电脑纯净绿色好用的软件
  7. NVIDIA CUDA初级教程(P2-P3)CPU体系架构概述、并行程序设计概述
  8. mysql异地双活架构,银行跨数据中心数据库双活架构设计:五大难点攻克
  9. 集成学习(ensemble learning)干货系列(3)——Boosting方法详解
  10. WM_CTLCOLOR消息重载