物化视图全量刷新与insert的redo生成量测试(69天)

之前的一篇博客中提到,物化视图的全量刷新也是一种高可用性的体现,但是性能如何呢,下面来简单的测试一下。

首先需要创建一个函数,这个函数会计算当前session下的一些指标信息。比如redo的生成量。

  CREATE OR REPLACE FUNCTION "GET_STAT_VAL" (p_name in varchar2) 
   return number 
as 
l_val number; 
begin 
select b.value into l_val from v$statname a,v$mystat b 
where a.statistic#=b.statistic# 
and a.name=p_name; 
return l_val; 
end;
/

然后创建一个shell脚本test.sh,这样就可以直接来运行sql语句,马上得到结果了。脚本内容如下:

sqlplus -s xxx/xxxx <<EOF 
set echo on 
set feedback off 
variable redo number 
exec :redo :=get_stat_val('redo size'); 
prompt start to gather redo size ... 
set serveroutput on 
set timing on 
alter system flush buffer_cache; 
$1 
--prompt finished gather redo size ... 
set timing off 
exec dbms_output.put_line((get_stat_val('redo size')-:redo)||' bytes of redo generated...'); 
EOF 
exit

首先来创建基表

SQL> create table tab_test tablespace pool_data as select *from dba_objects;
Table created.
SQL> select bytes from dba_segments where segment_name='TAB_TEST';
     BYTES 
---------- 
   2097152

然后使用Insert into tab_test select *from tab_test;然数据自增。达到24M左右的样子。

SQL> select bytes from user_segments where segment_name='TAB_TEST';
     BYTES 
---------- 
 24117248
SQL> commit;
Commit complete.

创建物化视图,默认使用全量刷新,可以看到生成的redo和物理段的大小基本一致。

$ ksh test.sh "create materialized view mv_test as select *from tab_test;" 
start to gather redo size ... 
Elapsed: 00:00:00.11 
Elapsed: 00:00:02.87 
23327504 bytes of redo generated...

然后创始全量刷新,发现redo量有了极大的增长,一下子达到了100多M. 响应时间从2秒一下子涨到了13秒。

$  ksh test.sh "exec dbms_mview.refresh('MV_TEST','C'); " 
start to gather redo size ... 
Elapsed: 00:00:00.83 
Elapsed: 00:00:13.36 
102212976 bytes of redo generated...

是不是所有的场景下全量刷新都会这么慢呢,看下面的例子。先truncate掉,然后再次全量刷新。发现响应时间一下子又恢复了2秒的样子。

$ ksh test.sh "truncate table mv_test;" 
start to gather redo size ... 
Elapsed: 00:00:25.13 
Elapsed: 00:00:00.17 
65220 bytes of redo generated...
$ ksh test.sh "exec dbms_mview.refresh('MV_TEST','C');" 
start to gather redo size ... 
Elapsed: 00:00:15.02 
Elapsed: 00:00:01.65 
23112468 bytes of redo generated...

如果已经刷新过,再次刷新,redo量又开始达到100M左右,我感觉物化视图刷新的过程中,对已有数据的刷新,又要删除原有数据,又要保证数据的读一致性,可能在实现上性能不够理想。

$ ksh test.sh "exec dbms_mview.refresh('MV_TEST','C');" 
start to gather redo size ... 
Elapsed: 00:00:14.86 
Elapsed: 00:00:11.13 
102370296 bytes of redo generated... 
$

下面来看看普通表的Insert性能相比物化视图刷新的情况,创建表insert_test。

首先来测试一下表在nologging的时候redo的情况,可以看到redo生成量只有118k左右。

create with nologging 
$ ksh test.sh "create table insert_Test tablespace pool_data nologging as select *from tab_test;" 
start to gather redo size ... 
Elapsed: 00:00:23.48 
Elapsed: 00:00:02.88 
117892 bytes of redo generated...

毕竟nologging使用的场景有限,在没有确认备份和业务需要的时候,不建议这么做。来看看默认使用Logging的时候。redo生成量和物理段基本一致。

create with logging 
$ ksh test.sh "create table insert_test tablespace pool_data as select *from tab_test;"          
start to gather redo size ... 
Elapsed: 00:00:00.08 
Elapsed: 00:00:01.96 
23291008 bytes of redo generated...

然后尝试truncate以后,使用insert插入数据。

$ ksh test.sh "truncate table insert_test;" 
start to gather redo size ... 
Elapsed: 00:00:00.06 
Elapsed: 00:00:00.16 
62956 bytes of redo generated...

如果使用insert append的方式插入,测试的这个库在archive的模式下,可以看到性能没有什么变化。

$ ksh test.sh "insert into /*+append */ insert_test select *from  tab_test;" 
start to gather redo size ... 
Elapsed: 00:00:03.15 
Elapsed: 00:00:01.60 
23085680 bytes of redo generated...

使用常规的insert的时候,redo生成量也没有明显的变化。

ksh a.sh "insert into insert_test select *from tab_test;" 
start to gather redo size ... 
Elapsed: 00:00:00.09 
Elapsed: 00:00:01.34 
23078764 bytes of redo generated...

这么看materialized view和insert的性能没有明显的差别。

可以考虑使用parallel让性能提升一个层次。

首先设置object级别的parallel

$ ksh a.sh " alter table insert_test parallel 2;" 
start to gather redo size ... 
Elapsed: 00:00:00.06 
Elapsed: 00:00:00.08 
2224 bytes of redo generated...

然后开启session级别的parallel,就是在test.sh里面加入一句

alter session enable parallel dml;

然后执行,可以看到redo的生成量才18K的样子,性能确实有了很大的提升。

ksh a.sh "insert into insert_test select *from tab_test;" 
start to gather redo size ... 
Elapsed: 00:00:00.10 
Elapsed: 00:00:00.01 
Elapsed: 00:00:04.19 
17908 bytes of redo generated...

看到并行的效果这么明显,难道物化视图刷新就没有并行吗,可以的,不过性能也确实没有什么提升,不知道自己设置的参数不够合理还是本来物化视图的实现细节复杂。

ksh a.sh "exec dbms_mview.refresh('MV_TEST','C',PARALLELISM=>2);" 
start to gather redo size ... 
Elapsed: 00:00:24.23 
Elapsed: 00:00:11.30 
102474472 bytes of redo generated...

由上可以看到,物化视图的刷新在性能和灵活性上没有普通表那么灵活。生成的Redo量要比普通表多,但是考虑到高可用性的使用,还是不错的选择,毕竟物化视图的优点不在于此,增量刷新和查询重写才是它的亮点所在。

原文发布于微信公众号 - 杨建荣的学习笔记(jianrong-notes)

原文发表时间:2014-05-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏

使用splice实现高效的代理服务器

很多网络应用场景下, 当原设备与目标设备无法直接建立连接时,这时就需要一台代理服务器进行中转。代理服务器只需要将来自源设备的报文 原封不动的转发给目标设备,而并...

1839
来自专栏A周立SpringCloud

最简日志打印规范

个人认为,如果在公司的野蛮生长阶段,一些基础类库不做约束,很可能“埋坑”,形成技术债务,最终为此付出代价。本文讲解一个最简的日志打印规范。 事实上,日志打印规范...

3717
来自专栏Rgc

项目中记录影响性能的缓慢数据库查询

如果程序性能随着时间推移不断降低,那很有可能是因为数据库查询变慢了,随着数据库规模的增长,这一情况还会变得更糟。优化数据库有时很简单,需要在程序和数据库之间加入...

33911
来自专栏Java帮帮-微信公众号-技术文章全总结

Hibernate_day02总结

Hibernate_day02总结 今日内容 l Hibernate持久化对象的状态 l Hibernate的一级缓存 l Hibernate操作持久化对象的方...

34511
来自专栏芋道源码1024

分布式事务 TCC-Transaction 源码分析 —— TCC 实现

本文主要基于 TCC-Transaction 1.2.3.3 正式版 1. 概述 2. TCC 原理 3. TCC-Transaction 原理 4. 事务与参...

1.1K8
来自专栏坚毅的PHP

PHP码农在Golang压力下的生存之道-PHP性能优化实践

随着国内Golang的火爆,phper的生存压力越来越大,在一次内部技术讨论中,gopher甚至提出,要什么php,写php的全部开掉,唉,码农何苦为难码农。 ...

6258
来自专栏岑玉海

hbase源码系列(三)Client如何找到正确的Region Server

  客户端在进行put、delete、get等操作的时候,它都需要数据到底存在哪个Region Server上面,这个定位的操作是通过HConnection.l...

40711
来自专栏Java帮帮-微信公众号-技术文章全总结

记一次sql server 性能调优,查询从20秒至2秒

记一次sql server 性能调优,查询从20秒至2秒 一、需求 需求很简单,就是需要查询一个报表,只有1个表,数据量大约60万左右,但是中间有些逻辑。 先说...

2776
来自专栏Java3y

数据库两大神器【索引和锁】

所以说,如果我们写select * from user where username = 'Java3y'这样没有进行任何优化的sql语句,默认会这样做:

970
来自专栏沃趣科技

Oracle Real Time SQL Monitoring

术语说明 TableQueue,消息缓冲区,在并行操作中使用,用于PX进程之间的通信,或者PX进程与QC进程之间的通信,是内存中的一些page,每个消息缓冲区的...

4018

扫描关注云+社区