作者小头像 Lv.2
63 成长值

个人介绍

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

感兴趣或擅长的领域

暂无数据
个人勋章
  • 活跃之星
成长雷达
0
63
0
0
0

个人资料

个人介绍

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

感兴趣或擅长的领域

暂无数据

达成规则

发布时间 2021/04/16 21:53:13 最后回复 方向 2021/04/30 16:32:17 版块 数据库
5256 45 0
他的回复:
报名读书会《SQL优化核心思想》Oracle的Cost计算公式单块读耗时:IO寻道寻址耗时+块大小/IO传输速度,典型的估算值:10+8K/4K=12ms多块读耗时IO寻道寻址耗时+db_file_multiblock_count*块大小/IO传输速度,SQL优化的核心思想就是想方设法减少SQL的物理I/O次数(不管是单块读次数还是多块读次数)徐老师还说,可以理解为减少sql 扫描的数据块数。即使有缓存,减少块的扫描次数也可以降低CPU的占用。read by other session等待这个等待事件其实是oracle IO问题一个比较尴尬的场景,会话a在进行把磁盘上的数据块读到内存(data buffer cache)中这个操作,会话b,会话c 同时也请求这个数据块。因为会话a还完全读入内存(data buffer cache),就导致了b,c read by other session。一般情况下组合索引的 引导列 是基数高的列列基数太低,而且没有收集直方图,CBO认为该列数据分布是均衡的,导致在估算Rows的时候,直接以表总行数/列基数来进行估算套循环内表的索引一定要包含连接列,如果只有过滤条件的索引就不应该选择嵌套循环,因为内表同样的数据要被扫描很多遍,不如选择hash join优化SQL需要注意表与表之间关系,分页语句只能对一个表的列进行排序, 而且排序列上应覆盖索引分页查询:查询Top 10的EMPt表的数据,要求按照工资降序。select 的列应避免在列上进行表达式。小表与大表关联,如果大表连接列基数比较高,可以走嵌套循环,让小表驱动大表,大表走连接列的索引加materialize提示:Oracle会先将查询结果写入一张临时表,然再查询临时表。WITH AS:就是将一个子查询部分独立出来,有时候是为了提高SQL语句的可读性,有时候是为了提高SQL语句性能。如果一个SQL语句中,某个表会被访问多次,而且每次访问的限制条件一样的话,就可以使用with as来提高性能。注意:如果with as 短语没有被调用2次以上,CBO就不会将with as短语获取的数据放入temp表,如果想要将数据放入temp表需要使用materialize hintOracle10g,where子查询中有主表的过滤条件,在not exists子查询中添加HINT:HASH_AJ无法更改执行计划。我们可以将not exists改写为“外连接+子表连接列is null”的形式,让其走HASH连接如果SQL语句本身没有绑定变量,但是执行计划中谓词过滤信息又有绑定变量(:B1,:B2,B3..),这说明有绑定变量这步需要传值。典型的需要传值的有标量子查询、Filter以及树形查询中start with 子查询。当执行计划中某个步骤需要传值,这个步骤就会被扫描多次。分区索引:如果过滤条件中有分区字段,一般都创建本地索引。如果过滤条件中没有分区字段,一般都创建global索引,如果这时创建成local索引,会扫描所有的索引分区,分区数量越多,性能下降越明显。假设有1 000个分区,在进行索引扫描的时候会扫描1 000个索引分区,此时相比global索引,会额外多读取至少1 000个索引块。NO.3:推荐朋友参与读书会:将任意读书会链接分享或活动海报(上方竖图)到≥10人的群或朋友圈,截图
发布时间 2020/03/31 10:24:39 最后回复 wei 2020/04/29 18:13:38 版块 训练营
29716 114 1
他的回复:
华为云账号: renzhuangzhuang 微信昵称:成事书名 BOOK TITLE《SQL优化核心思想》阅读心得 LEARNINGS关联更新优化UPDATE后面跟子查询类似嵌套循环,它的算法与标量子查询,Filter一模一样批量更新,MERGE语句性能最好,因为它可以多块读,并且可以并行执行,但是缺点就是消耗比较多的UNDO,一旦down机死事物恢复较慢。外连接有OR关联条件只能走NL当两表用外连接进行关联,关联条件中有OR关联条件,那么这时只能走嵌套循环,而且驱动表固定为主表,此时不能走HASH连接,即使通过HINT:USE_HASH也无法修改执行计划。如果主表数据量很大,那么这时就会出现严重性能问题。可以将外连接的OR关联/过滤条件放到查询中,对于从表的列用case when进行过滤,从而让SQL可以走HASH连接。把你脑袋当CBO扩展统计信息oracle 11g在统计信息收集方面增加了扩展统计信息的特性,它可以收集一个表中相关列上的统计信息,也可以收集函数表达式上的统计信息.使选择率,成本的估计更加准确,也更容易走正确的执行计划.在相关列上收集统计信息,好处还是很明显的.例如两列在逻辑上有一定的关系,但如果只是对这两个列单独做统计信息的收集,根据多条件的选择率计算(A AND B的选择率为:OPSEL[a]*OPSEL[b]),估算出来的选择率就可能偏差很大。wm_concat返回的是CLOB类型,性能比较差,尽量使用Listagg代替。Listagg返回的是VARCHAR.SQL中关联条件是instr,这时只能走嵌套循环,不能走HASH连接,也不能走排序合并连接,排序合并连接一般用于>=,>,,=.exists效率和 in:如果where子查询中没有固化子查询关键字,不管写成in还是写成exists,效率都是一样的,因为CBO始终能将子查询展(unnest)如果where子查询中有固化子查询关键字,这时我们最好用in而不是exists,因为in可以控制子查询是否展开,而exists无法展开。至于where子查询是展开性能好还是不展开性能好,我们要具体情况具体分析。指定hash join连接谓词就不会下推。怎么才可以让优化器知道真实Rows呢?我们可以使用HINT:CARDINALITY./*+ cardinality(a 10000) */表示指定a表有1万行数据。/*+ cardinality(@a 10000) */表示指定queryblocka有1万行数据。或者使用动态采样,或者直接指定正确外键没创建索引的表建议在外键列上创建索引,外键列不创建索引容易导致死锁。级联删除的时候,外键列没有索引会导致表被全表扫描。需要收集直方图的列当一个表比较大,列选择性(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性能。抓出走了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语句中是否有其他过滤条件,如果有其他过滤条件,可以考虑建立组合索引,将选择性高的列作为引导列。