果然视图的效率永远是跟不上表的啊
工作上的原因开始接触Oracle了...虽然Oracle在几年前就玩过了,但是基本上都是最基本得操作了,简单的存储过程,简单的触发器.....
现在到了新的公司,碰到了诡异的问题是一个针对地区的统计问题.
一个省下面有许多的市,需要统计这些市出现的次数,以及外省的数字.
本来这个是一个非常容易搞定的问题,但是现在却碰到了麻烦,那就是这个地址字段里面存放的并不是地区的代码而是地区的文本....orz
于是现在如果想要统计这种要么通过不断的LIKE来做Count(ID),然后UNION ALL形成最终结果了...但是仅仅面对20万左右的数据量,这条语句的执行时间居然长达3分钟以上.
然后想了一个办法,首先将所有符合条件的数据全部用视图的方式UNION ALL起来,添加一个虚拟的地区代码字段,然后再对这个视图做Group BY操作.
可惜,就算是这样做了,也仅仅只是把时间提升到了2分钟10秒左右.
没办法,只有想办法改动表结构了...我是一直不怎么想改动这个表结构的,因为不是我设计的,而且本身设计的很糟糕... 程序也是刚刚接手,都没办法整理,所以如果变动了表结构,就一定要通过触发器来解决后续的问题了...
不过抱着尝试的心态,添加了一个字段,然后简单的用LIKE来更新这个字段.
然后再用Group By来生成报表.这时惊人的效率提升终于出现了..只用了5秒.
但是只有20万的数据量的话,用5秒似乎也显得太多了一点 ,估计是没有使用到索引...
于是添加索引,以Where语句的字段和Group By后面的字段添加联合索引.再做测试...
速度终于提升到0.15秒左右了...正常范围内了(虽然赶不上MySQL的效率了,当然,这也是必然的)...
接下来就是触发器了...以前只是写过一个自增ID字段的触发器而已,而且还是网上直接抄下来的...
不过现在这个触发器也很简单就是了...所需要实现的就是在Insert字段的时候根据既有的字段中的某一个值(所在地区)得取值来确定我添加的那个字段的取值.并且将更新了的数据插入进去就可以了.
但是不得不说,我根本就忘了触发器怎么写了....orz
不过最后还是搞定了就是了...之前忘掉了使用for each row,导致一直都报告ORA-04082错误,添加那个字段后终于搞定了...这个字段的含义是,缺省的触发器是语句级别的,如果添加了这个字段就会变成行级别,可以对语句所涉及到的每一行都做操作,对于Insert而言,这自然就是对刚刚Insert进来的这一行了...
最终的样子如下:
现在到了新的公司,碰到了诡异的问题是一个针对地区的统计问题.
一个省下面有许多的市,需要统计这些市出现的次数,以及外省的数字.
本来这个是一个非常容易搞定的问题,但是现在却碰到了麻烦,那就是这个地址字段里面存放的并不是地区的代码而是地区的文本....orz
于是现在如果想要统计这种要么通过不断的LIKE来做Count(ID),然后UNION ALL形成最终结果了...但是仅仅面对20万左右的数据量,这条语句的执行时间居然长达3分钟以上.
然后想了一个办法,首先将所有符合条件的数据全部用视图的方式UNION ALL起来,添加一个虚拟的地区代码字段,然后再对这个视图做Group BY操作.
可惜,就算是这样做了,也仅仅只是把时间提升到了2分钟10秒左右.
没办法,只有想办法改动表结构了...我是一直不怎么想改动这个表结构的,因为不是我设计的,而且本身设计的很糟糕... 程序也是刚刚接手,都没办法整理,所以如果变动了表结构,就一定要通过触发器来解决后续的问题了...
不过抱着尝试的心态,添加了一个字段,然后简单的用LIKE来更新这个字段.
然后再用Group By来生成报表.这时惊人的效率提升终于出现了..只用了5秒.
但是只有20万的数据量的话,用5秒似乎也显得太多了一点 ,估计是没有使用到索引...
于是添加索引,以Where语句的字段和Group By后面的字段添加联合索引.再做测试...
速度终于提升到0.15秒左右了...正常范围内了(虽然赶不上MySQL的效率了,当然,这也是必然的)...
接下来就是触发器了...以前只是写过一个自增ID字段的触发器而已,而且还是网上直接抄下来的...
不过现在这个触发器也很简单就是了...所需要实现的就是在Insert字段的时候根据既有的字段中的某一个值(所在地区)得取值来确定我添加的那个字段的取值.并且将更新了的数据插入进去就可以了.
但是不得不说,我根本就忘了触发器怎么写了....orz
不过最后还是搞定了就是了...之前忘掉了使用for each row,导致一直都报告ORA-04082错误,添加那个字段后终于搞定了...这个字段的含义是,缺省的触发器是语句级别的,如果添加了这个字段就会变成行级别,可以对语句所涉及到的每一行都做操作,对于Insert而言,这自然就是对刚刚Insert进来的这一行了...
最终的样子如下:
create OR REPLACE trigger BI_ACCEPT before Insert on WX_ACCEPT for each row Begin if :new.APPEAL_ADDRESS LIKE '%武汉%' then :new.LOCATION_NAME := 1; elsif :new.APPEAL_ADDRESS LIKE '%黄石%' then :new.LOCATION_NAME := 2; elsif :new.APPEAL_ADDRESS LIKE '%十堰%' then :new.LOCATION_NAME := 3; elsif :new.APPEAL_ADDRESS LIKE '%宜昌%' then :new.LOCATION_NAME := 4; elsif :new.APPEAL_ADDRESS LIKE '%襄樊%' OR :new.APPEAL_ADDRESS LIKE '%襄阳%' then :new.LOCATION_NAME := 5; elsif :new.APPEAL_ADDRESS LIKE '%鄂州%' then :new.LOCATION_NAME := 6; elsif :new.APPEAL_ADDRESS LIKE '%荆门%' then :new.LOCATION_NAME := 7; elsif :new.APPEAL_ADDRESS LIKE '%孝感%' then :new.LOCATION_NAME := 8; elsif :new.APPEAL_ADDRESS LIKE '%荆州%' then :new.LOCATION_NAME := 9; elsif :new.APPEAL_ADDRESS LIKE '%黄冈%' then :new.LOCATION_NAME := 10; elsif :new.APPEAL_ADDRESS LIKE '%咸宁%' then :new.LOCATION_NAME := 11; elsif :new.APPEAL_ADDRESS LIKE '%随州%' then :new.LOCATION_NAME := 12; elsif :new.APPEAL_ADDRESS LIKE '%恩施%' then :new.LOCATION_NAME := 13; elsif :new.APPEAL_ADDRESS LIKE '%仙桃%' then :new.LOCATION_NAME := 14; elsif :new.APPEAL_ADDRESS LIKE '%潜江%' then :new.LOCATION_NAME := 15; elsif :new.APPEAL_ADDRESS LIKE '%天门%' then :new.LOCATION_NAME := 16; elsif :new.APPEAL_ADDRESS LIKE '%神农架%' then :new.LOCATION_NAME := 17; end if; end;
评论
发表评论