文盲的数据库指令优化心得:第二部分,指令变形和执行计划

本文主要是介绍文盲的数据库指令优化心得:第二部分,指令变形和执行计划,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先,文盲先写了四个语句,这四个预计得到的结果集是完全相同的,但是第一个语句对索引的要求最多,也是我们平时所写的语句格式,因为这么写起来字符最少,维护方便。。。。。。但是从效率和索引维护上来将,第一条语句其实不是最好的,所以,我们产生了三中变形,分别是exists子查询,apply子查询,join子查询


select id from test_index where n1>40 and n5<100 order by n5select main.id from test_index main  
inner join (select id,n5 from test_index where n5<100) app_n5 on main.id=app_n5.id  
where n1>40 and n2=n2 and b1=b1 and d1=d1  
order by app_n5.n5 select a.id from (select id from test_index where n1>40 and n2=n2 and b1=b1 and d1=d1) a
cross apply(select n5 from test_index where n5<100 and id=a.id) n5
order by n5select a.id from test_index a where n5<100
and exists(select top 1 1 from test_index where id=a.id and n1>40 and n2=n2 and b1=b1 and d1=d1)
order by n5

exists 是直接跟随在where之后的,但是,这个子查询得到的结果是无法参与下一步计算的,比如order,所以可以看到第四个语句的查询主条件已经变了,这个说实话,不太方便,那么 exists 的使用范围就限定了,只能是条件,但不能参与更进一步的运算


再看看join,这个关联查询到时可以返回多个字段参与下一步运算,但是join语句无法直接使用主语句返回的结果,所以如果需要使用主查询的结果集,就需要把运算写在on语句里,十分麻烦,尤其是无法直接使用表值函数对主查询的值进行计算,这点反而是exists可以做到


最后看看apply,首先,这个指令可以直接使用主查询的结果,其次,由apply提供的列可以参与下一步计算,所以apply的适用范围更广,好了变形方式第一个知识点完毕


然后再看看这些指令的下一组比较

select id from test_index where n1>40 and (n5<100 or n5 is null)SQL Server 分析和编译时间: CPU 时间 = 0 毫秒,占用时间 = 18 毫秒。(367267 行受影响)
表 'test_index'。扫描计数 5,逻辑读取 21319 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。SQL Server 执行时间:CPU 时间 = 405 毫秒,占用时间 = 815 毫秒。



select id from test_index where n1>40 and isnull(n5,0)<100SQL Server 分析和编译时间: CPU 时间 = 0 毫秒,占用时间 = 13 毫秒。(367267 行受影响)
表 'test_index'。扫描计数 5,逻辑读取 21319 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。SQL Server 执行时间:CPU 时间 = 266 毫秒,占用时间 = 786 毫秒。



select id from test_index where n1>40 and n5<100
union
select id from test_index where n1>40 and n5 is nullSQL Server 分析和编译时间: CPU 时间 = 0 毫秒,占用时间 = 6 毫秒。(367267 行受影响)
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'test_index'。扫描计数 2,逻辑读取 20936 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。SQL Server 执行时间:CPU 时间 = 172 毫秒,占用时间 = 761 毫秒。


select id from test_index a 
where n1>40 and n2=n2 and b1=b1 and d1=d1
and exists(select 1 from test_index where isnull(n5,0)<100 and id=a.id)SQL Server 分析和编译时间: CPU 时间 = 6 毫秒,占用时间 = 6 毫秒。(367267 行受影响)
表 'test_index'。扫描计数 10,逻辑读取 10574 次,物理读取 0 次,预读 9 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。SQL Server 执行时间:CPU 时间 = 544 毫秒,占用时间 = 869 毫秒。



select id from test_index a
where n1>40 and n2=n2 and b1=b1 and d1=d1
and exists(select 1 from test_index where n5<100 and id=a.id union select 1 from test_index where n5 is null and id=a.id)SQL Server 分析和编译时间: CPU 时间 = 14 毫秒,占用时间 = 14 毫秒。(367267 行受影响)
表 'test_index'。扫描计数 11,逻辑读取 7022 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。SQL Server 执行时间:CPU 时间 = 578 毫秒,占用时间 = 838 毫秒。



select a.id from test_index a
inner join (select id from test_index where isnull(n5,0)<100) b on a.id=b.id
where n1>40 and n2=n2 and b1=b1 and d1=d1SQL Server 分析和编译时间: CPU 时间 = 16 毫秒,占用时间 = 18 毫秒。(367267 行受影响)
表 'test_index'。扫描计数 10,逻辑读取 10574 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。SQL Server 执行时间:CPU 时间 = 468 毫秒,占用时间 = 824 毫秒。



select a.id from test_index a
inner join (select id from test_index where n5<100 union select id from test_index where n5 is null) b on a.id=b.id
where n1>40 and n2=n2 and b1=b1 and d1=d1SQL Server 分析和编译时间: CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。(367267 行受影响)
表 'test_index'。扫描计数 11,逻辑读取 7022 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。SQL Server 执行时间:CPU 时间 = 577 毫秒,占用时间 = 818 毫秒。



select id from test_index a
cross apply (select n5 from test_index where isnull(n5,0)<100 and id=a.id) b
where n1>40 and n2=n2 and b1=b1 and d1=d1SQL Server 分析和编译时间: CPU 时间 = 0 毫秒,占用时间 = 21 毫秒。(367267 行受影响)
表 'test_index'。扫描计数 10,逻辑读取 10574 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。SQL Server 执行时间:CPU 时间 = 515 毫秒,占用时间 = 898 毫秒。



select id from test_index a
cross apply (select n5 from test_index where n5<100 and id=a.id union select n5 from test_index where n5 is null and id=a.id) n5
where n1>40 and n2=n2 and b1=b1 and d1=d1SQL Server 分析和编译时间: CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。(367267 行受影响)
表 'test_index'。扫描计数 5,逻辑读取 11025992 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。SQL Server 执行时间:CPU 时间 = 6786 毫秒,占用时间 = 2340 毫秒。



select id from test_index a
cross apply (select n5 from (select id,n5 from test_index where n5<100 union select id,n5 from test_index where n5 is null) b where id=a.id) n5
where n1>40 and n2=n2 and b1=b1 and d1=d1SQL Server 分析和编译时间: CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。(367267 行受影响)
表 'test_index'。扫描计数 11,逻辑读取 7022 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。SQL Server 执行时间:CPU 时间 = 594 毫秒,占用时间 = 820 毫秒。



好了,同一个条件的,同样索引情况下的各种变形指令列出来了9种,可以看到,执行计划即便是全部是索引查找的也未必一定的最快的,比如最第九个语句,而在语句中存在了列计算或者or的时候,则变成了索引扫描,所以,到底一个实际的应用到底效率如何,还是需要把指令拿出来具体分析,统计一下到底如何写效率才是最高的


关于条件中出现or要用union代替,别人说过了,列参与计算会变成索引扫描,别人说过了,使用索引来提速,前一篇也说过了。。。。那么在这组比较中我们发现,第七条指令和第十条指令相对较快,执行计划相对合理,那么根据这组比较来看,我们对查询指令的优化并无定向,只能试试各种方式看看到底如何才能得到最高效率的查询方式


我么由此得到结论,指令的各种变形会直接影响到索引的使用和执行计划的规划,所以,多试试各种写法,对提高查询指令效率是有帮助的

----------------------------------------------------------------------------------------

文盲的数据库指令优化心得:第一部分,关于索引

文盲的数据库指令优化心得:第二部分,指令变形和执行计划


SQL SERVER全面优化-------Expert for SQL Server 诊断系列


这篇关于文盲的数据库指令优化心得:第二部分,指令变形和执行计划的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/746659

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

闲置电脑也能活出第二春?鲁大师AiNAS让你动动手指就能轻松部署

对于大多数人而言,在这个“数据爆炸”的时代或多或少都遇到过存储告急的情况,这使得“存储焦虑”不再是个别现象,而将会是随着软件的不断臃肿而越来越普遍的情况。从不少手机厂商都开始将存储上限提升至1TB可以见得,我们似乎正处在互联网信息飞速增长的阶段,对于存储的需求也将会不断扩大。对于苹果用户而言,这一问题愈发严峻,毕竟512GB和1TB版本的iPhone可不是人人都消费得起的,因此成熟的外置存储方案开

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

MySQL数据库宕机,启动不起来,教你一招搞定!

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间

csu(背包的变形题)

题目链接 这是一道背包的变形题目。好题呀 题意:给n个怪物,m个人,每个人的魔法消耗和魔法伤害不同,求打死所有怪物所需的魔法 #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>//#include<u>#include<map

hdu3389(阶梯博弈变形)

题意:有n个盒子,编号1----n,每个盒子内有一些小球(可以为空),选择一个盒子A,将A中的若干个球移到B中,满足条件B  < A;(A+B)%2=1;(A+B)%3=0 这是阶梯博弈的变形。 先介绍下阶梯博弈: 在一个阶梯有若干层,每层上放着一些小球,两名选手轮流选择一层上的若干(不能为0)小球从上往下移动,最后一次移动的胜出(最终状态小球都在地面上) 如上图所示,小球数目依次为

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份