暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

71-对2010年阿里一道Oracle DBA面试题目的分析

据说这是一个2010年阿里面试Oracle DBA的面试题,来自某公众号,作者当年面试阿里Oracle DBA时亲历,称之为“拒人于千里之外的SQL题”:


“有一张以 ID 为主关键字的聚集表,表数据量是 2 亿。要将另一张同样结构的表,表数据量是 6000 万,合并到第一张表里。


请你设计一个更新的过程。第一张表可能含有 第二张表的部分数据,也可能没有。没有的要插入,匹配的要更新。


是一个典型的merge操作,只不过数据量大了一些。表上有没有分区,占用多少存储空间,有多少索引,是否需要中断业务,这些都是比较重要的条件,都没有提及,说明这是一个开放式的问题。


作者在文章中没有给出解题思路,我谈谈自己的想法:


方法1、不管表有没有分区,直接用merge开启并行dml,这个数据量在硬件条件还可以的系统,也不是问题,与方法2、3相比,效率就一般般。这个方法的关键是要开启并行dml。知道使用merge,能得点分;再加上会启用并行dml,应该也能勉强及格吧。这个要看面试官出题的出发点了。


方法2、还是merge,两个表都设计成按id 做相同hash 分区的分区表,同时开启并行DML,效率会有很大提升,因为这个会用到oracle的partition wise join技术。在硬件条件(主要是存储吞吐量)还可以的情况下,开个32个并行,如果没有索引,一两分钟应该能解决战斗。如果面试者在2010年能知道PWJ这个知识点,这个答案过面试官这一关应该没问题,因为到了2019年,了解这个知识点的人也不多(在某些书上还能看到有优化大师用手工实现类似partition wise join实现的方法,不知道是不是不想用并行的缘故。大表做类似操作,并行必须用啊)。


方法3、创建相同表结构新表,原来两表做full outer join,插入数据到新表,然后再rename,这种方法效率最高。如果表上还有索引,那更是首选方法,可以插入数据后再创建索引。这个方法再配合partition wise join、并行dml、nologging、compress技术,如果存储够强悍,一分钟内解决战斗完全没问题。


方法4、11g版本开始提供了一个分片并行的方法:DBMS_PARALLEL_EXECUTE。可以把6000万的表,按照rowid或是其他方式进行分片(本题不能对2亿的表做分片),如果有60个分片,那么每个分片只需要处理100万记录即可。这种方法需要使用plsql,操作起来有点复杂。每个100万记录的分片与2亿记录的表做merge,如果逐条做Nested loop,走索引效率不高;如果用Hash join,则2亿大表要扫描60次,效率都不行。优点就是可以减少回滚段的使用(相比方法1和2)。这种方法可能也是很多程序员的思维,大表分段,开启游标,逐条处理,效率是真的不行。


总结:

      方法3效率最高方法2简单效,需要分区配合方法1效率一般方法4对单表操作的dml还可以,在本例,也不合适。


    上面是我能想到的几个方法,不知道阿里的面试官自己的出题和解题思路是什么,说不定还有更高级的方法。

    

(完)

最后修改时间:2019-12-20 09:29:24
文章转载自老虎刘谈oracle性能优化,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论