oracle物化视图使用的个人见解

场景:公司某项目,共计2KW数据,业务需要在这2KW数据中进行查询。

早期的分析:单表2KW,如果查询的话,每次都要查2KW,而且这张表经常要进行数据写入和修改,担心效率不高,所以考虑将其拆分为10张字段完全相同的表,写入和修改分别在这10张表中进行。另外,由于查询需要查总体,所以考虑使用视图。

早期对于物化视图和普通视图的选择:

1、物化视图:从字面意思来理解,是将结果已经准备好,物理化成一张表,然后每次查询,就在这张表中进行(同时,这张表也可以建索引)

2、普通视图:将语句集合成一个整体,每次查询的时候,只要查这个视图,数据库会自动将视图中的语句替换出来,进行查询。但每次查询其实还是分别去查了N张表,和一条一条写语句没有差别

最后的方案:将2KW拆分成字段完全相同的10张表,然后将10张表所有字段联合建立物化视图,每天凌晨同步物化图,并在物化视图建立索引。采用全量同步(不采用增量同步的原因是因为这2kw数据经常会变化,所以增量同步未必会比全量更快)

 

实际运行中遇到的坑:

1、每天凌晨同步的时候,有时候会出现索引丢失的情况(至今未查明为什么会出现索引丢失),导致第二天查询效率及其缓慢,连接数越堆越多导致数据库卡死,后来采用存储过程手动重建物化视图,也未能解决这个问题

2、每次卡死之后,要恢复整个服务非常麻烦,主要原因是每次重启数据库完成后,物化视图会自动开始运行,无法结束,在完全断开应用服务的情况下,跑一次2kw的重建物化视图,需要15分钟左右。(由于数据库先卡死,所以没办法手动关闭重建物化视图的dba_jobs,只能眼睁睁看着它开始重建)

3、灵异现象,我们的同步定时任务是设置在每天凌晨的,但偶尔会在下午4、5点突然开始运行重建,原因至今不明,后果就是莫名的数据库卡死。。系统无法访问。。

 

解决方案:

经过多次不胜其烦的物化视图同步导致数据库卡死事件之后。。我重新分析了一下物化视图和普通视图的优劣,并从执行计划和实际语句运行时间对比后发现:

1、执行计划:由于10张子表都有相同的索引,所以虽然是联立10张表查询,但效率依旧是很可观的。从执行计划上看,开销与物化视图+索引不相上下。

2、实际语句运行:查单条记录的时间相差无几,查统计值的时间甚至普通视图更快。

3、普通视图无需每天同步这种繁琐操作,也就不存在索引失效问题(子表数据虽然一直有更新,但从未出现索引失效的情况)

4、普通视图可能会因为子表数据正在修改引起一些性能上的浮动,但经过观察,表示这部分性能影响非常有限,完全可以在可接受的范围内

综上所述,我将生产环境的物化视图改为了普通视图,并且目前运行稳定,再未出现原先时不时卡死现象。

 

对于物化视图的思考:

1、物化视图确实是将结果事先准备好,应该会更快才对,那为什么查询上却和普通视图比没有优势呢?

答:因为这个"结果"的问题,比如我从2kw本书中找一本书,那么这2kw本书,堆在一个房间,和堆在10个房间,对于计算机来说,其实是没有什么差别的(人类进房间出房间要时间,但是计算机来说,忽略不计)

2、那么物化视图适用于哪些场景?

答:还是“结果”的问题,有什么样的“结果”会需要事先准备?那就是需要计算的结果,例如,这2kw本书的各种分类汇总统计,如果是用普通视图,那就会每次查询的时候去算,那是很慢的,这时候就可以采用物化视图,将计算结果事先准备好,放到物化视图中,这样在查询的时候,直接拎结果就很快了,并且还附带了一个优势:自动同步,无需我们自己再去写存储过程再设置定时执行,在建立物化视图的时候,这些工作就都做好了

 

你可能感兴趣的:(SQL)