作者小头像 Lv.1
9 成长值

个人介绍

这个人很懒,什么都没有留下

感兴趣或擅长的领域

暂无数据
个人勋章
TA还没获得勋章~
成长雷达
0
9
0
0
0

个人资料

个人介绍

这个人很懒,什么都没有留下

感兴趣或擅长的领域

暂无数据

达成规则

他的回复:
云享读书会•程序员修炼之道 day4读书笔记微信昵称:阿静华为云账号:hw66179654day4 敏捷项目管理团队讲述需求之坑、携手共建。敏捷的本质。维持小而稳定的团队,组织全功能团队等内容一、项目启动之前45.需求之坑无人确切知道自己想要什么程序员帮助人们理解他们想要什么需求是重反馈循环中学到的和用户一起工作以便从用户角度思考策略及元数据使用项目术语表46.处理无法解决的难题不要跳出框框思考找到框框在面对无法解决的难题时,识别出真正的约束,可以问自己“必须这样做才能搞定吗,必须搞定它吗?47.携手共建不要一个人埋头钻进代码中编程往往困难有费力,找个朋友和你一起干敏捷不是一个名词,敏捷有关你如何做事敏捷是一个形容词,有关如何做事情48.敏捷的本质个体和互动高于流程和工具工作好软件高于详尽的文档客户合作高于合同谈判响应变化高于遵循计划二、务实的项目49.务实的团队维持小而稳定的团队排上日程以待其成组织全功能的团队50.椰子派不上用场能起作用的事,别赶时在用户需要时交付。51.务实的入门套件使用版本控制来驱动构建,测试和发布尽早测试,经常测试,自动测试直到所有测试都已运行,编码才算完成使用破坏者检测你的测试测试状态覆盖率,而非代码覆盖率每个bug只找一次不要使用手动测试52.取悦用户取悦用户,而不要只是交付代码53.傲慢与偏见在作品上签名过去的工匠在为他们的作品签名时非常自豪,你也应该这样。
他的回复:
云享读书会•程序员修炼之道 day3读书笔记微信昵称:阿静华为云账号:hw66179654day3 软件编程并发讲述打破时域耦合。角色与进程;讲述软件编码-巧合式编程、算法速度、重构等。一、编程的并发33.打破时域耦合通过分析作流来提高并发性利用用户工作流中的并发性34.共享状态是不正确的状态共享状态是不正确的状态共享状态会带来无穷的麻烦,而且往往只有重启才能解决随机障通常是并发问题获取时间和上下文的变化能暴露并发bug,但并发bug无法始终保持一致,也很难重现35.角色与进程用角色实现并发性时不必共享状态使用角色来管理并发状态,可以避免显示的同步36.黑板使用黑板来协调工作流37.听从蜥蜴脑听你内心的蜥蜴当编程举步维艰时,其实是潜意识字告诉你有什么地方不对38.巧合式编程不要依赖巧合式编程不要做差不多先生39.算法速度评估算法的级别在开始编程前,对这件事情大概会花多长时间要有概念对评估做测试针对算法的数学分析无法说明所有问题,尝试在目标环境中测试执行代码的耗时。40.重构尽早重构,经常重构二、当你编码时,你会怎么做?41.为编码测试测试与找bug无关测试是代码的第一个用户既非自上而下,也不自下而上,基于端对端构建为测试做设计要对软件做测试,否则只能留个用户去做42.基于特性做测试43.出门在外注意安全保持代码简洁,让攻击面最小敏感信息加密尽早打上安全补丁 44.事物命名好好取名,需要是更名用名字向读者表达你的意图,并且在意图改变是及时更名。
他的回复:
云享读书会•程序员修炼之道day2读书笔记微信昵称:阿静华为云账号:hw66179654day2 软件编程认知讲述契约式设计,死掉的程序不会说谎、断言式编程等;讲述编程的弹性、变换时编程、继承税、配置等一、软件编程基础工具16.纯文本的威力将知识用纯文本保存纯文本不会过时。它能够让你的工作事半功倍,并能简化调试和测试工作17.Shell游戏发挥Shell命令的威力当图形化界面无法胜任时,使用shell.18.加强编辑能力游刃有余地使用编辑器既然编辑器是至关重要的工具,不妨了解一下如何使用它更快更准19.版本控制永远使用版本控制版本控制为你的工作创造了一个时间机器,可以用它重返过去。20.调试去解决问题,而不是责备Bug到底来自你的失误还是别人的失误真的不重要,他终究是的问题,需要你来修复不要恐慌不管是对银河系搭车客,还是对开发者来说,都应这样修改代码前先让代码在测试中失败在你修改bug前,先创建一个聚焦于该bug的测试。读一下那些该死的出错信息大多数异常都能告诉失败之物与失败之处,如果足够幸运,你甚至能得到具体的参数值“select ” 没出问题在操作系统或编译器中发现问题非常罕见,甚至在第三方产品或库中也是如此,Bug大多数出现在应用程序中。不要假设,要证明在真实环境中证实你的假设,--- 要依赖真实的数据集。二、务实的偏执21.文本处理学习一门文本处理语言既然每天都要花大量的时间与文本打交道,何不让计算机帮你分担一二22.工程日记你无法写出完美的软件软件不可能是完美的,对于在所难免的错误,要保护代码和用户免受其影响。23.契约式设计通过契约进行设计代码是否不多不少刚好完成它宣传要做的事情,可以使用契约加一校验和文档化。24.死掉的程序不会说谎尽早崩溃彻底死掉的程序往往比有缺陷的程序造成的伤害要小。25.断言式编程使用断言去预防不可能的事情26.如何保持资源的平衡有始有终只要有可能,对资源进行分配的函数或对象就有责任区释放该资源27.不要冲出前灯范围小步前进曲由始至终,永远小步前进,不断检查反馈,并在推进前先做调整28.解耦解耦代码让变更更容易耦合使事物紧紧绑定在一起,以至于很难只改变其中之一只管命令不要询问不要从对象中取出值,在加以变换后再塞回去,让对象自己来完成这些工作不要链式调用方法当访问某事物时,使用的点号不要超过一个避免全局数据最好给每个方法增加一个额外的参数如果全局唯一非常重要,那么将它包装到AP中,但是,仅限于你真的非常希望他是全局的。29.在现实世界中抛球杂耍不同状态直接的转换,要用状态机处理三、宁弯不曲30.变换式编程编程讲的是代码,而程序谈的是数据所有的程序都在变换数据----将输入转换成输出,开始用变换方式来设计吧不要囤积状态,传递下去不要把数据保持在函数或模块的内部,拿出来传递下去31.继承税不要付继承税考虑一下能更好满足需求的替换方案,比如接口,委托或mixin尽量用接口来表达多态无需继承引入耦合,接口就能明确描述多状态用委托提供服务,"有一个"胜过“是一个”不要从服务中继承,应该包含服务利用mixin共享功能mixin不必承担继承税就可以给类添加功能,而与接口结合可以让多态不再令人痛苦32.配置使用外部配置参数化应用程序如果一下代码对一些应用程序发布后还有可能改变的值有所依赖,那么就在应用外部来维护这些值
他的回复:
云享读书会•程序员修炼之道 day1读书笔记微信昵称:阿静华为云账号:hw66179654day1 软件编程哲学务实的智学:1,人生是你的你有选择权   人生是自己的,把握住人生,让它如你所愿2.我的源码被猫吃了,-- 提供选择,别找借口提供选择而不是去找理由,不要只说做不到,解释一下都能做到什么。3.软件的熵不要放任何破窗只要看到不好的设计、错误的决策、糟糕的代码,就赶紧去纠正4.石头做的汤和煮熟的青蛙做推动变革的催化剂你无法强迫人们去改变,但可以展示美好的未来,并帮助他们参与创造 ,牢记愿景,不要过度沉浸于细枝末叶以免察觉不到周围正在发生的事情。5.够好即可的软件将质量要求视为需求问题让用户参与对项目真实质量需求的确定6.知识组合对知识组合做定期投资  ,而不是单一的投资养成学习的习惯,做到学习的多样性,像人工智能批判性地分析你读到和听到的东西7.交流说什么和怎么说同样重要 如果无法有效交流,任务伟大的想法都是没有意义的。8.优秀设计的精髓优秀的设计比糟糕的设计更容易变更适合使用者的事务,都已经良好的设计,对代码来说,就必须适应变化9.DAY**的重复不要重复自己系统中的每一条知识,都必须有单一且无歧义的权威称述让服用变得更容易只有复用方便,人们就会去做,创建一个支持复用的环境10.正交性消除不相关事务之间的影响设计的组成,需要自成一体,独立自主,有单一的清晰定义的意图11.可逆性不设最终决定不要把决定刻在石头上,而是将其视为写在沙滩上的东西,时刻装备应变放弃追逐时尚昨日之最佳实践,即明日之反模式,要基于基本原则去选择架构,而不盲从于流行。12.曳光弹使用曳光弹找到目标通过不断尝试并看清着弹点,曳光弹可确保你最终击中目标13.原型与便签用原型学习制作设计原型旨在学习经验,其价值不在于过程中产生的代码,而不在于得到的教训。14.领驭语靠近问题域编程用问题领域的语言来做设计和编程在计算机里有一些领域的东西,比如说计算机里面有一些领域的东西,如何考虑一些静态类型、面向对象,函数啊,对领域方面的编程,这些都需要根据编程语言,对软件的需求进行设计和实现15.估算通过估算来避免意外 开始之前的估算,能提前发现潜在问题根据代码不断迭代进度表开始之前的估算,能提前发现潜在问题16.领驭语靠近问题域编程用问题领域的语言来做设计和编程
发布时间 2020/03/31 10:24:39 最后回复 wei 2020/04/29 18:13:38 版块 社区活动
29636 114 1
他的回复:
微信昵称:阿静华为云账号:hw66179654第2天学习笔记一:嵌套循环  NESTED LOOP嵌套循环的算法驱动表返回一行数据,驱动表返回多少行,被驱动表就要被扫描多少次在执行计划中,离 nested loops关键字最近的表就是驱动表嵌套循环使用场景驱动表应该返回少量数据,关联条件的索引命中的数据必须很少。提问:两表关联走不走NL是看两个表关联之后返回的数据量多少?还是看驱动表返回的数据量多少?所以判断两表关联是否应该走NL应该直接查看两表关联之后返回的数据量,如果两表关联之后返回的数据量少,可以走NL;返回的数据量多,应该走HASH连接。此外,还需要关注被驱动表的过滤条件和是否需要回表提问:select * from a,b where a.id=b.id; 如果a有100条数据,有100万行数据,a与b是1∶N关系,N很低,应该怎么优化SQL?回答:因为a与b是1∶N关系,N很低,我们可以在b的连接列(id)上创建索引,让a与b走嵌套循环(a nl b),这样b表会被扫描100次,但是每次扫描表的时候走的是id列的索引(范围扫描)。外联结使用嵌套循环 (nest loop anti)当两表使用外连接进行关联,如果执行计划是走嵌套循环,那么这时无法更改驱动表,驱动表会被固定为主表。思考为什么?为什么外连接的从表有过滤条件会变成内连接呢?因为外连接的从表有过滤条件已经排除了从表与主表没有关联上显示为NULL的情况。嵌套循环的提示use_nl(d,e)表示让两表走嵌套循环,在书写HINT的时候,如果表有别名,HINT中一定要使用别名,否则HINT不生效;如果表没有别名,HINT中就直接使用表名。提问:两表关联走不走NL是看两个表关联之后返回的数据量多少?还是看驱动表返回的数据量多少?回答:如果两个表是1∶N关系,驱动表为1,被驱动表为N并且N很大,这时即使驱动表返回数据量很少,也不能走嵌套循环,因为两表关联之后返回的数据量会很多。所以判断两表关联是否应该走NL应该直接查看两表关联之后返回的数据量,如果两表关联之后返回的数据量少,可以走NL;返回的数据量多,应该走HASH连接。此外,还需要关注被驱动表的过滤条件和是否需要回表提问:大表是否可以当嵌套循环(NL)驱动表?回答:可以,如果大表过滤之后返回的数据量很少就可以当NL驱动表。提问:select * from a,b where a.id=b.id; 如果a有100条数据,b有100万行数据,a与b是1∶N关系,N很低,应该怎么优化SQL?回答:因为a与b是1∶N关系,N很低,我们可以在b的连接列(id)上创建索引,让a与b走嵌套循环(a nl b),这样b表会被扫描100次,但是每次扫描表的时候走的是id列的索引(范围扫描)。二:HASH连接HASH连接的适用场景哈希连接只支持等值连接。哈希连接的适用场景就是嵌套循环的不适用场景,即两表连接条件关联的结果集比较大。Used-Mem表示HASH连接消耗了多少PGA,当驱动表太大、PGA不能完全容纳驱动表时,驱动表就会溢出到临时表空间,进而产生磁盘 HASH连接,这时候HASH连接性能会严重下降。嵌套循环不需要消耗PGA。思考:怎么优化HASH连接?回答:因为HASH连接需要将驱动表的select列和join列放入PGA中,所以,我们应该尽量避免书写select * from....语句,将需要的列放在select list中,这样可以减少驱动表对PGA的占用,避免驱动表被溢出到临时表空间,从而提升查询性能。外连接的HASH对于左外连接,Oracle会选择小表为hash表(执行计划上面的表)。Oracle如果想改变hash表,需要使用swap_join_inputs提示(leading不起作用)。三.排序合并连接(SORT MERGE JOIN)适用场景排序合并连接主要用于处理两表非等值关联,比如>,>=,,=,,但是不能用于instr、substr、like、regexp_like关联,instr、substr、like、regexp_like关联只能走嵌套循环。如果两表是等值关联,一般不建议走排序合并连接。因为排序合并连接需要将两个表放入PGA中,而HASH连接只需要将驱动表放入PGA中,排序合并连接与HASH连接相比,需要耗费更多的PGA。算法介绍排序合并连接的算法:两表关联,先对两个表根据连接列进行排序,将较小的表作为驱动表,然后从驱动表中取出连接列的值,到已经排好序的被驱动表中匹配数据,如果匹配上数据,就关联成功。驱动表返回多少行,被驱动表就要被匹配多少次,这个匹配的过程类似嵌套循环,但是嵌套循环是从被驱动表的索引中匹配数据,而排序合并连接是在内存中(PGA中的workarea)匹配数据。思考:怎么优化排序合并连接?回答:如果两表关联是等值关联,走的是排序合并连接,我们可以将表连接方式改为HASH连接。如果两表关联是非等值关联,比如>,>=,,=,,这时我们应该先从业务上入手,尝试将非等值关联改写为等值关联,因为非等值关联返回的结果集“类似”于笛卡儿积,当两个表都比较大的时候,非等值关联返回的数据量相当“恐怖”。如果没有办法将非等值关联改写为等值关联,我们可以考虑增加两表的限制条件,将两个表数据量缩小。四.笛卡儿连接(CARTESIAN JOIN)什么是笛卡儿连接两个表关联没有连接条件的时候会产生笛卡儿积,这种表连接方式就叫笛卡儿连接。执行计划中MERGE JOIN CARTESIAN就表示笛卡儿连接。在多表关联的时候,两个表没有直接关联条件,但是优化器错误地把某个表返回的Rows算为1行(注意必须是1行),这个时候也可能发生笛卡儿连接。思考:当执行计划中有笛卡儿连接应该怎么优化呢?首先应该检查表是否有关联条件,如果表没有关联条件,那么应该询问开发与业务人员为何表没有关联条件,是否为满足业务需求而故意不写关联条件。其次应该检查离笛卡儿连接最近的表是否真的返回1行数据,如果返回行数真的只有1行,那么走笛卡儿连接是没有问题的,如果返回行数超过1行,那就需要检查为什么Rows会估算错误,同时要纠正错误的Rows。纠正错误的Rows之后,优化器就不会走笛卡儿连接了。我们可以使用HINT /+opt_param('_optimizer_mjc_enabled', 'false') / 禁止笛卡儿连接。五.标量子查询(SCALAR SUBQUERY)什么是标量子查询?当一个子查询介于select与from之间,这种子查询就叫标量子查询 。标量子查询类似一个天然的嵌套循环,而且驱动表固定为主表。标量子查询中子查询的表连接列也必须包含在索引中。图片:标量子查询优化建议尽量避免使用标量子查询,假如主表返回大量数据,主表的连接列基数很高,那么子查询中的表会被多次扫描,从而严重影响SQL性能。当SQL里面有标量子查询,我们可以将标量子查询等价改写为外连接,从而使它们可以进行HASH连接。六.半连接(SEMI JOIN)什么是半连接?两表关联只返回一个表的数据就叫半连接。半连接一般就是指的in和exists。 in和exists一般情况下都可以进行等价改写。半连接和内连接的等价写法(性能不如半连接)A . 半连接以子查询为驱动,对主表嵌套循环适用于子查询的数据集非常小并且主表有索引的场景。Oracle hint小技巧1。对于in子查询可以用/*+ qb_name(a) */定义子查询,然后在提示中用a引用对应的表2。Oracle会为每个查询块定义一个名字,提示中也可以用这个名字,block名字通过下面这种方式获得B. 以主表为驱动表,对子查询嵌套循环以主表为Hash表做hash连接适用于主表数据集较少,子查询连接条件有索引的场景C.以主表为Hash表做hash连接适用于两表连接结果集比较大,主表较小的场景D.以子表为Hash表做hash连接适用于两表连接结果集比较大,子表较小的场景思考题现有如下SQL:select * from a where a.id in (select id from b);假设a有1000万,b有100行,请问如何优化该SQL?以a为主表,为a.id 添加索引;b为子表, 然后对2表进行半连接查询假设a有100行,b有1000万,请问如何优化该SQL?以a为主表;b为子表,为b.id 添加索引, 然后以主表为hash表做hash连接假设a有100万,b有1000万,请问如何优化该SQL?以a为主表;b为子表,然后以主表为hash表做hash连接七.反连接(ANTI JOIN)什么是反连接?两表关联只返回主表的数据,而且只返回主表与子表没关联上的数据,这种连接就叫反连接。反连接一般就是指的not in和not exists。SQL> select * from dept where deptno not in (select deptno from emp);SQL> select * from dept where not exists (select null from emp where dept.deptno = emp.deptno);not in和not exists的区别not in的话,只要子查询中有一个null,结果就为空,而not exists不会,说明not in认为null是未知的,可以等于任意数。将not exists等价改写为not in的时候,要注意null。一般情况下,如果反连接采用not in写法,我们需要在where条件中剔除null。not in和not exists的执行计划1)嵌套循环Not in要指定is not null或者有非空约束,注意:驱动表必须是主表2)hash连接Not in要指定is not null或者有非空约束,否则可能会很慢,如果想改变hash表,可以使用提示swap_join_inputs思考题现有如下SQL1)select * from a where a.id not in (select id from b where id is not null);假设a 有1000万条,b有1000条,请问如何优化该SQL?以a为主表,为a.id 添加索引;b为子表, 然后对2表进行半连接查询假设a有1000条,b有1000万条,请问如何优化该SQL?以a为主表;b为子表,为b.id 添加索引, 然后以主表为hash表做hash连接假设a有100万条,b有1000万条,请问如何优化该SQL?以a为主表;b为子表,然后以主表为hash表做hash连接2)IN与EXISTS谁快谁慢?第一:IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。第二:若子查询结果集较小,in执行的就快,相反,Exsts执行的就快3)SQL语句性能优化的本质是什么?SQL优化的本质就是:1、缩短响应时间;2、提升系统吞吐量;3、提升系统负载能力。八.子查询无法展开什么叫子查询展开以及为什么要展开SELECT * FROM sales WHERE cust_id IN ( SELECT cust_id FROM customers );就是优化器将嵌套的子查询展开成一个等价的join,然后去优化这个join。上面的语句,不展开的情形是,从sales表中获取的每1条数据,都要代入子查询进行匹配。一般情况下效率都是比较低的。展开的结果可能是将sales表和customers表做一个hash join semi,从而提高效率。因为转换为join后可以从访问路径、连接方法、连接顺序等方面优化整个查询。如果子查询不能展开,执行计划一般会显示为filter,类似嵌套循环,固定以主表为驱动表。在Oracle中,如果子查询有or条件或者rownum条件,往往会出现这种情况。此时效率可能非常低,要避免出现,or语句可以改造为union。四.  三种连接工作方式比较:     Hash join的工作方式是将一个表(通常是小一点的那个表)做hash运算,将列数据存储到hash列表中,从另一个表中抽取记录,做hash运算,到hash 列表中找到相应的值,做匹配。        Nested loops 工作方式是从一张表中读取数据,访问另一张表(通常是索引)来做匹配,nested loops适用的场合是当一个关联表比较小的时候,效率会更高。 Merge Join 是先将关联表的关联列各自做排序,然后从各自的排序表中抽取数据,到另一个排序表中做匹配,因为merge join需要做更多的排序,所以消耗的资源更多。通常来讲,能够使用merge join的地方,hash join都可以发挥更好的性能。
发布时间 2020/03/31 10:24:39 最后回复 wei 2020/04/29 18:13:38 版块 社区活动
29636 114 1
他的回复:
微信昵称:阿静华为云账号:hw66179654第三天学习笔记Oracle的Cost计算公式Cost =(单块读耗时+多块读耗时+CPU耗时)/单块读的耗时Cost是语句的预计执行时间的总和,以单块读取时间为单位的形式来表示。单块读耗时IO寻道寻址耗时+块大小/IO传输速度,典型的估算值:10+8K/4K=12ms多块读耗时IO寻道寻址耗时+db_file_multiblock_count*块大小/IO传输速度,如果db_file_multiblock_count配置16,则多块读耗时为42msCPU耗时评估出的CPU占用/CPU主频/1000,该值一般比IO耗时低得全表扫描Cost评估全表扫描没有单块读,CPU耗时可以忽略,它的cost约等于多块读的cost全表扫描的多块读次数=Block数量/db_file_multiblock_count,由于IO中断和多个extent不连续,实际值会略大。索引范围扫描Cost评估索引范围扫描没有多块读,CPU耗时可以忽略,它的cost约等于单块读的cost索引范围扫描单块读的次数=blevel+celiling(leaf_blocks*effective index selectivity) +celiling(clustering_factor* effective table selectivity)包括三部分:索引层高-1,需要扫描的索引块的个数,需要回表的次数,其中主要部分是需要回表的次数。优化器何时选择全表扫描,何时选择索引扫描?就是比较走全表扫描的总耗时与走索引扫描的总耗时,哪个快就选哪个。IO代价的变化全表扫描成本计算公式是在Oracle9i(2000年左右)开始引入的,当时的I/O设备性能远远落后于现在的I/O设备(磁盘阵列),随着SSD的出现,寻道寻址时间已经可以忽略不计,磁盘阵列的性能已经有较大提升,因此认为在现代的I/O设备(磁盘阵列)中,单块读与多块读耗时几乎可以认为是一样的SQL优化的核心思想就是想方设法减少SQL的物理I/O次数(不管是单块读次数还是多块读次数)。即使有缓存,减少块的扫描次数也可以降低CPU的占用。全表扫描Cost评估全表扫描没有单块读,CPU耗时可以忽略,它的cost约等于多块读的cost全表扫描的多块读次数=Block数量/db_file_multiblock_count,由于IO中断和多个extent不连续,实际值会略大。索引范围扫描Cost评估索引范围扫描没有多块读,CPU耗时可以忽略,它的cost约等于单块读的cost索引范围扫描单块读的次数=blevel+celiling(leaf_blocks*effective index selectivity) +celiling(clustering_factor* effective table selectivity)包括三部分:索引层高-1,需要扫描的索引块的个数,需要回表的次数,其中主要部分是需要回表的次数。优化器何时选择全表扫描,何时选择索引扫描?就是比较走全表扫描的总耗时与走索引扫描的总耗时,哪个快就选哪个。IO代价的变化全表扫描成本计算公式是在Oracle9i(2000年左右)开始引入的,当时的I/O设备性能远远落后于现在的I/O设备(磁盘阵列),随着SSD的出现,寻道寻址时间已经可以忽略不计,磁盘阵列的性能已经有较大提升,因此认为在现代的I/O设备(磁盘阵列)中,单块读与多块读耗时几乎可以认为是一样的SQL优化的核心思想就是想方设法减少SQL的物理I/O次数(不管是单块读次数还是多块读次数)。即使有缓存,减少块的扫描次数也可以降低CPU的占用
发布时间 2020/03/31 10:24:39 最后回复 wei 2020/04/29 18:13:38 版块 社区活动
29636 114 1
他的回复:
微信昵称:阿静华为云账号:hw66179654第5天学习笔记1.SQL审核规则外键没创建索引的表建议在外键列上创建索引,外键列不创建索引容易导致死锁。级联删除的时候,外键列没有索引会导致表被全表扫描。需要收集直方图的列当一个表比较大,列选择性(NDV/num_rows)低于5%,而且列出现在where条件中,为了防止优化器估算Rows出现较大偏差,我们需要对这种列收集直方图。必须创建索引的列当一个表比较大,列选择性超过20%,列出现在where条件中并且没有创建索引,我们可以对该列创建索引从而提升SQL查询性能。抓出表被多次反复调用SQL在开发过程中,我们应该避免在同一个SQL语句中对同一个表多次访问。我们可以通过下面SQL抓出同一个SQL语句中对某个表进行多次扫描的SQL。抓出走了FILTER的SQL当where子查询没能unnest,执行计划中就会出现FILTER,对于此类SQL,我们应该在上线之前对其进行改写,避免执行计划中出现FILTER。抓出返回行数较多的嵌套循环SQL两表关联返回少量数据应该走嵌套循环,如果返回大量数据,应该走HASH连接,或者是排序合并连接。如果一个SQL语句返回行数较多(大于1万行),SQL的执行计划在最后几步(Id=5)走了嵌套循环,我们可以判定该执行计划中的嵌套循环是有问题的,应该走HASH连接。抓出NL被驱动表走了全表扫描的SQL嵌套循环的被驱动表应该走索引。抓出走了TABLE ACCESS FULL的SQL如果一个大表走了全表扫描,会严重影响SQL性能。2. SQL审核规则抓出走了INDEXFULL SCAN的SQLINDEX FULL SCAN会扫描索引中所有的叶子块,单块读。如果索引很大,执行计划中出现了INDEX FULL SCAN,这时SQL会出现严重的性能问题。抓出走了INDEX SKIP SCAN的SQL当执行计划中出现了INDEX SKIP SCAN,通常说明需要额外添加一个索引。抓出索引被哪些SQL引用有时开发人员可能会胡乱建立一些索引,但是这些索引在数据库中可能并不会被任何一个SQL使用。这样的索引会增加维护成本,我们可以将其删掉。抓出走了笛卡儿积的SQL当两表没有关联条件的时候就会走笛卡儿积,当Rows被估算为1的时候,也可能走笛卡儿积连接。抓出走了错误的排序合并连接的SQL排序合并连接一般用于非等值关联,如果两表是等值关联,我们建议使用HASH连接代替排序合并连接,因为HASH连接只需要将驱动表放入PGA中,而排序合并连接要么是将两个表放入PGA中,要么是将一个表放入PGA中、另外一个表走INDEXFULL SCAN,然后回表。如果两表是等值关联并且两表比较大,这时应该走HASH连接而不是排序合并连接。抓出走了低选择性索引的SQL如果一个索引选择性很低,说明列数据分布不均衡。当SQL走了数据分布不均衡列的索引,很容易走错执行计划,此时我们应该检查SQL语句中是否有其他过滤条件,如果有其他过滤条件,可以考虑建立组合索引,将选择性高的列作为引导列。抓出可以创建组合索引的SQL(回表再过滤选择性高的列)回表次数太多会严重影响SQL性能。当执行计划中发生了回表再过滤并且过滤字段的选择性比较高,我们可以将过滤字段包含在索引中避免回表再过滤,从而减少回表次数,提升查询性能。抓出可以创建组合索引的SQL(回表只访问少数字段)回表次数太多会严重影响SQL性能。当SQL走索引回表只访问表中少部分字段,我们可以将这些字段与过滤条件组合起来建立为一个组合索引,这样就能避免回表,从而提升查询性能。