物化视图中的统计信息导致的查询问题分析和修复 (r7笔记第47天)

时间:2022-05-04
本文章向大家介绍物化视图中的统计信息导致的查询问题分析和修复 (r7笔记第47天),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

今天开发的同事下午反馈给我一个问题,说有操作直接卡住了,听这个描述,感觉很可能是查询慢了。 于是连接到环境中,查看了一下正在执行的sql语句情况,发现下面的语句已经执行了一段时间。 语句类似下面的形式: select t1.SECURITY_PHONE as MOBILE_PHONE, t1.SECURITY_EMAIL as OTHER_EMAIL, t2.* from accstat.ACCOUNT_DELTA t1, bidata.TMP_CN06 t2 where t1.CN_MASTER = t2.CN 其实对于这个查询,看起来条件也蛮简单的,但是为什么查询慢呢。 首先得了解一下这个问题的背景。

目前的这个库是一个统计库,库里的数据是从账号库中分库分表的12个用户中得来,就如同左边所示,是放在了4个分库,12个用户中,表名都是account_delta 目前采用是物化视图的增量刷新来实现,使得数据能够每天按时增量刷新到统计库中。统计库中也存在一套类似的结构,也是12个相似的表,不过在统计库中为了增量刷新我们采用了物化视图。 然后对外是使用一个account_delta的视图来实现。 所以现在的情况是account_delta和另外一个临时表关联,则实际意味着实际上是12个物化视图和1个表在关联。 那么到底慢在哪里了,我们来看看执行计划,可以看到12个物化视图都毫无例外走了全表扫描。当然整个执行计划的消耗那是非常惊人的。

初步怀疑是索引导致的,但是发现两个表中的cn字段索引都存在。 然后继续查看发现了一个不同之处。TMP_CN06中的字段cn是varchar2(70),而account_delta中的cn_master是 varchar2(50),感觉这里似乎有点关联,但是自己实在是想不出到底哪里可能有问题,于是把TMP_CN06中的字段cn改为了 varchar2(50),其实内容是在varchar2(50)之内的。但是改了之后查看执行计划还是没有任何改善,还是全表扫描。 这个时候问题催的也非常着急,这个时候也在犹豫是不是因为多个物化视图导致了这个问题。 为了尽快修复问题,一边排查一遍开始准备复制一份数据来,表中的数据量非常大,最后开了并行的复制。最后还是一个ora错误收场。这个时候时间又过去了十多分钟。 create table accstat.ACCOUNT_DELTA_ALL as select *from accstat.ACCOUNT_DELTA * ERROR at line 1: ORA-12801: error signaled in parallel query server P010 ORA-01652: unable to extend temp segment by 8192 in tablespace ACCSTAT_DATA Elapsed: 00:16:14.85 这个时候尝试分片思想。把第二个分片的数据导入表中,大概持续了8分钟左右。不过按照这个速度还是有很大的差距。剩下的11个分片数据量都不小。 SQL> insert into accstat.ACCOUNT_DELTA_all select *from ACCSTAT.ACC02_ACCOUNT_DELTA ; commit; 52074945 rows created. Elapsed: 00:08:07.24 好了,我们还是放弃这种数据复制的方法,开始琢磨到底能不能做点什么。 继续分片,拿出一个分片和表TMP_CN06关联,然后查看执行计划,发现这个时候就走了索引扫描,而且执行的代价也小了很多。

好了,这些尝试都做完了,我们来看看末尾的dynamic sampling的情况,一般的物化视图可能我们也就是纯粹为了增量刷新,也基本没有动过统计信息。我采用了下面的方式来收集统计信息。 exec DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=> 'ACCSTAT', TABNAME =>'ACC04_ACCOUNT_DELTA' ,CASCADE =>TRUE,METHOD_OPT=>'FOR ALL INDEXED COLUMNS SIZE 1',DEGREE =>4, GRANULARITY =>'ALL'); 剩下的11个都是如法炮制,操作很快就完成了。 那么等我做完11个之后,再次查看执行计划还是全表扫描,还是提示dynamic sampling。直到我收集完全之后,再次查看执行计划。就变成了下面的形式。

虽然看起来似乎会有些冗长,不过总体来看还是不错的。因为我们确实需要TMP_CN06走全表扫描。 那么我们再次尝试这个过程,时间就变为了惊人的3秒。TMP_CN06表中有近10万的记录,也没有走并行。 create table test_201551214 as select t1.SECURITY_PHONE as MOBILE_PHONE, t1.SECURITY_EMAIL as OTHER_EMAIL, * t2.* from accstat.ACCOUNT_DELTA t1, bidata.TMP_CN06 t2 where t1.CN_MASTER = t2.CN; Table created. Elapsed: 00:00:03.27 所以从这个程度来看,物化视图堆叠起来的视图性能其实也差不了,用不好就会感觉差。也算是对物化视图的一个重新认识吧。 这个问题其实之前有同事反馈过,当时也是思路全在物化视图日志上下功夫了,准备解析物化视图日志来做一个merge的操作,最后也是无功而返,也对物化视图的操作产生了一些误解,看来这种情况下,性能也照样差不了。我已经试过水了,所以这种情况还是值得推广的。