Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1148904
  • 博文数量: 231
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 2662
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-03 16:35
个人简介

学无止境

文章分类

全部博文(231)

文章存档

2014年(7)

2013年(103)

2011年(11)

2010年(53)

2009年(57)

分类: Oracle

2010-11-21 16:30:05

本实验目标是实现查询重写。
假设有1个视图,是2张基表连接,每次查询该视图,都需要对2张表进行全表扫描再连接。
2张基本都没有涉及索引。
如果使用物化连接,开销更小。
利用查询重写,不改动sql文本内容的情况下,执行计划走物化视图。

查询重写需要成本更低才会走查询重写。


创建用户liaody:

CREATE USER LIAODY IDENTIFIED BY LIAODY;
ALTER USER LIAODY TABLESPACE LDY;

分配权限,需要有query rewrite和创建物化视图的权限。

GRANT CREATE SESSION TO LIAODY;
GRANT RESOURCE TO LIAODY;
GRANT QUERY REWRITE TO LIAODY;
grant create view to liaody;
grant create materialized view to liaody;

参数query_rewrite_enabled 需要是true。

NAME                                 TYPE        VALUE
------------------------------------ ----------- ----------
query_rewrite_enabled                string      TRUE
query_rewrite_integrity              string      enforced


创建2张表:

create table qrw01
(id number,
a1 char(10),
a2 char(10),
a3 CHAR(10),
a4 CHAR(10),
a5 CHAR(10),
other1 CHAR(10),
other2 CHAR(10),
other3 CHAR(10)
);

 

create table qrw02
(id number,
a1 CHAR(10),
a2 CHAR(10),
a3 CHAR(10),
a4 CHAR(10),
a5 CHAR(10),
b1 CHAR(10),
b2 CHAR(10),
b33 CHAR(10)
);

生成数据插入表

begin
for i in 1..100000 loop
insert into qrw01 values (trunc(dbms_random.value(0,50)),
dbms_random.string('u', 2),dbms_random.string('u', 2),
dbms_random.string('u', 2),dbms_random.string('u', 2),
dbms_random.string('u', 2),dbms_random.string('u', 2),
dbms_random.string('u', 2),dbms_random.string('u', 2));
if mod(i,1000)=0 then
commit;
end if;
end loop;
end;
/


declare
varsql varchar2(200);
CURSOR mycur is
select id,a1,a2,a3,a4,a5
from qrw01;
begin
for i in 1..5 loop
for varsql in mycur loop
insert into qrw02
values (varsql.id,varsql.a1,varsql.a2,varsql.a3,varsql.a4,varsql.a5,
dbms_random.string('u', 2),dbms_random.string('u', 2),dbms_random.string('u', 2));
end loop;
commit;
end loop;
end;
/


2张表的数据量:

SQL> SELECT COUNT(*) FROM QRW02;

  COUNT(*)
----------
    500000

SQL> SELECT COUNT(*) FROM QRW01;

  COUNT(*)
----------
    100000
   
   
创建一个普通视图:

create view v_qrw01 as
select q1.id,
q1.other1,q1.other2,q1.other3,q2.b1,q2.b2,q2.b33
from qrw01 q1,qrw02 q2
where q1.id=q2.id
and q1.a1=q2.a1
and q1.a2=q2.a2
and q1.a3=q2.a3
and q1.a4=q2.a4
and q1.a5=q2.a5;

该视图查出来的数据量有50w。

SQL> select count(*) from v_qrw01;

  COUNT(*)
----------
    500000
   

下面一条语句的开销,2张表的全表扫描:

SQL> select id,other1,other2,other3,b1,b2,b33 from liaody.v_qrw01 where id=14;

已选择9845行。


执行计划
----------------------------------------------------------
Plan hash value: 151944771

----------------------------------------------------------------------------
| Id  | Operation          | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |       |    32 |  6976 |  1772   (1)| 00:00:22 |
|*  1 |  HASH JOIN         |       |    32 |  6976 |  1772   (1)| 00:00:22 |
|*  2 |   TABLE ACCESS FULL| QRW01 |  1990 |   211K|   304   (1)| 00:00:04 |
|*  3 |   TABLE ACCESS FULL| QRW02 |  8787 |   935K|  1467   (1)| 00:00:18 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("Q1"."ID"="Q2"."ID" AND "Q1"."A1"="Q2"."A1" AND
              "Q1"."A2"="Q2"."A2" AND "Q1"."A3"="Q2"."A3" AND "Q1"."A4"="Q2"."A4
" AND

              "Q1"."A5"="Q2"."A5")
   2 - filter("Q1"."ID"=14)
   3 - filter("Q2"."ID"=14)

Note
-----
   - dynamic sampling used for this statement


统计信息
----------------------------------------------------------
        179  recursive calls
          0  db block gets
       8864  consistent gets
          0  physical reads
          0  redo size
     782114  bytes sent via SQL*Net to client
       7601  bytes received via SQL*Net from client
        658  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
       9845  rows processed


在2张表上创建物化视图:

create materialized view log on qrw01 with rowid;
create materialized view log on qrw02 with rowid;

创建物化视图,查询语句和前面视图的语句相同。

create materialized view qrw_mv01
refresh fast
with rowid
on commit
enable query rewrite
as
select q1.rowid q1rowid,q2.rowid q2rowid,q1.id,
q1.other1,q1.other2,q1.other3,q2.b1,q2.b2,q2.b33
from qrw01 q1,qrw02 q2
where q1.id=q2.id
and q1.a1=q2.a1
and q1.a2=q2.a2
and q1.a3=q2.a3
and q1.a4=q2.a4
and q1.a5=q2.a5;

对表进行分析:

SQL> exec DBMS_STATS.GATHER_TABLE_STATS('liaody','qrw01');

PL/SQL 过程已成功完成。

SQL> exec DBMS_STATS.GATHER_TABLE_STATS('liaody','qrw02');

PL/SQL 过程已成功完成。

SQL> exec DBMS_STATS.GATHER_TABLE_STATS('liaody','qrw_mv01');

PL/SQL 过程已成功完成。

 


相同的sql,执行计划变为扫描物化视图。

SQL> select id,other1,other2,other3,b1,b2,b33 from liaody.v_qrw01 where id=14;

已选择9845行。

已用时间:  00: 00: 00.98

执行计划
----------------------------------------------------------
Plan hash value: 2499593068

-----------------------------------------------------------------------------------------
| Id  | Operation                    | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |          |  9935 |   669K|  1492   (1)| 00:00:18 |
|*  1 |  MAT_VIEW REWRITE ACCESS FULL| QRW_MV01 |  9935 |   669K|  1492   (1)| 00:00:18 |
-----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("QRW_MV01"."ID"=14)


统计信息
----------------------------------------------------------
         15  recursive calls
          0  db block gets
       7322  consistent gets
       3528  physical reads
          0  redo size
     781938  bytes sent via SQL*Net to client
       7601  bytes received via SQL*Net from client
        658  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       9845  rows processed
      
      


create view v_qrw02 as
select q1.id,
q1.other1,q1.other2,q1.other3,q2.b1,q2.b2,q2.b33
from qrw01 q1,qrw02 q2
where q1.id=q2.id
and q1.a1=q2.a1
and q1.a2=q2.a2
and q1.a3=q2.a3
and q1.a4=q2.a4
and q1.a5=q2.a5
and q1.id=10;      


SQL> select count(*) from v_qrw02;

  COUNT(*)
----------
      9845
     
以下一条sql语句:
select id,other1,other2,other3,b1,b2,b33 from liaody.v_qrw02;


该sql语句走的是QRW_MV01物化视图:
SQL> select id,other1,other2,other3,b1,b2,b33 from liaody.v_qrw02;

已选择9845行。

已用时间:  00: 00: 01.37

执行计划
----------------------------------------------------------
Plan hash value: 2499593068

-----------------------------------------------------------------------------------------
| Id  | Operation                    | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |          | 10417 |   701K|  1492   (1)| 00:00:18 |
|*  1 |  MAT_VIEW REWRITE ACCESS FULL| QRW_MV01 | 10417 |   701K|  1492   (1)| 00:00:18 |
-----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("QRW_MV01"."ID"=10)


统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       7324  consistent gets
       6655  physical reads
          0  redo size
     782070  bytes sent via SQL*Net to client
       7601  bytes received via SQL*Net from client
        658  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       9845  rows processed

 

创建一个新的物化视图qrw_mv02:

create materialized view qrw_mv02
refresh fast
with rowid
on commit
enable query rewrite
as
select q1.rowid q1rowid,q2.rowid q2rowid,q1.id,
q1.other1,q1.other2,q1.other3,q2.b1,q2.b2,q2.b33
from qrw01 q1,qrw02 q2
where q1.id=q2.id
and q1.a1=q2.a1
and q1.a2=q2.a2
and q1.a3=q2.a3
and q1.a4=q2.a4
and q1.a5=q2.a5
and q1.id=10;


同一条sql语句走了物化视图qrw_mv02,该成本更低。

SQL> select id,other1,other2,other3,b1,b2,b33 from liaody.v_qrw02;

已选择9845行。

已用时间:  00: 00: 00.20

执行计划
----------------------------------------------------------
Plan hash value: 434718022

-----------------------------------------------------------------------------------------
| Id  | Operation                    | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |          |  9600 |   796K|    33   (0)| 00:00:01 |
|   1 |  MAT_VIEW REWRITE ACCESS FULL| QRW_MV02 |  9600 |   796K|    33   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement


统计信息
----------------------------------------------------------
         42  recursive calls
          0  db block gets
        860  consistent gets
        132  physical reads
          0  redo size
     782279  bytes sent via SQL*Net to client
       7601  bytes received via SQL*Net from client
        658  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       9845  rows processed

阅读(943) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-11-22 17:23:27

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com