本人使用oracle时间不多,但是在项目中积累了一些经验教训,记录于此,以方便自己和他人解决类似的问题。
1.temp space超出限制的问题
问题场景:
在复杂的ETL query中,有时候一张fact表逻辑复杂,来自多张表的join,我习惯写成CTE的方式,
但CTE是放在内存中的,所以比较快捷,但如果数据量过大,则会spool到临时空间中,如果db server的配置不可观,则极有可能发生如此的错误。
解决方案:我之前在sqlserver上遇到的类似问题时,是直接into到物理表中,然后在物理表上创建索引,再用于后面的join.这边这里的同事使用MV(据说是oracle的银弹),把原来的复杂逻辑拆解成多个MV的方式,然后在后来调用的时候,就手工强制刷MV后再使用。
2.插入的数据中含有&
问题场景:
数据库中有两张静态配置表,数据需要我们手工写成INSERT INTO配置数据。发现插入的数据中含有&。如果直接在sqlplus或者在oracle sql develper 中报提示,因为 它们把&后面的字符串识别为变量。
解决方案:
使用set define off;这样就会把含有&的部分也识别为普通字符串。
3.FULL JOIN 的性能问题
问题场景:
ticket(问题描述单)中含有国家和区域,但是此处的国家和区域并不是完全匹配的,即和我们库中的标准的国家和区域表的关系不完全一致。我们需要做的是,根据一定的规则,匹配上正确的国家和区域之间的关系的话则保留,匹配不上的国家为空,区域也保留之类的。需要用到full join.
但问题是,我使用full join后这个MV就从几十秒变为二十分钟左右,让人无法忍受。数据量大概十多万。
解决方案:一同事搜索后,理解full join就是union full join 和 left join 的结果集,然后尝试把full join改写成 left join union right join,MV变回到十几秒就刷好了。
讨论个问题:
如何阅读复杂的sql?并发现可能的数据问题?
找到最基本的主表,关注表与表之间的join字段,看看是否有空值,会miss值。
看看表与表之间的关系是1:1还是M:N。