日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內(nèi)最全IT社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當前位置:首頁 > 數(shù)據(jù)庫 > 數(shù)據(jù)庫應(yīng)用 > oracle中約束(constraints)是如何影響查詢計劃的

oracle中約束(constraints)是如何影響查詢計劃的

來源:程序員人生   發(fā)布時間:2015-01-05 08:52:05 閱讀次數(shù):4232次
原文:http://www.oracle.com/technetwork/issue-archive/2009/09-may/o39asktom-096149.html


oracle中束縛(constraints)是如何影響查詢計劃的


通常人們認為束縛只是和數(shù)據(jù)完全性有關(guān),沒問題。但是束縛也被優(yōu)化器使用來優(yōu)化履行計劃。
優(yōu)化器會拿以下資源最為輸入inputs:


1)待優(yōu)化的查詢
2)所有數(shù)據(jù)庫對象統(tǒng)計
3)系統(tǒng)統(tǒng)計,如果可以獲得的話(CPU速度、單塊I/O速度等等作為物理硬件的衡量尺度)
4)初始化參數(shù)
5)束縛


我常常聽到人們在數(shù)據(jù)倉庫/報表系統(tǒng)中疏忽束縛的使用,理由是:數(shù)據(jù)本身OK,并且我們做了數(shù)據(jù)清洗(如果讓束縛enable,他們反而不高興),但事實證明為了取得更好的履行計劃他們的確需要數(shù)據(jù)完全性束縛。數(shù)據(jù)倉庫中1個差的履行計劃可能耗時幾小時乃至幾天才能履行完。下面我們通過實例來講明束縛對履行計劃的重要性:


1. 來看NOT NULL束縛如何影響履行計劃:
code1: 創(chuàng)建數(shù)據(jù)隔離的表和視圖
drop table t1;
drop table t2;
drop view v;


create table t1
as
select * from all_objects
where object_type in ('TABLE','VIEW');




alter table t1 modify object_type not null;


alter table t1 add constraint t1_check_otype check (object_type in('TABLE','VIEW'));




create table t2
 as
 select * from all_objects
 where object_type in ( 'SYNONYM', 'PROCEDURE' );




alter table t2 modify object_type not null;


alter table t2 add constraint t2_check_otype 
  check (object_type in ('SYNONYM', 'PROCEDURE'));




create or replace view v
as
select * from t1
union all
select * from t2;


code2: 優(yōu)化掉1個表
set autotrace traceonly explain
select * from v where object_type = 'TABLE';
Execution Plan
----------------------------------------------------------------------------
Plan hash value: 3982894595


-----------------------------------------------------------------------------
| Id  | Operation            | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |    40 |  6320 |   151   (1)| 00:00:02 |
|   1 |  VIEW                | V    |    40 |  6320 |         (1)| 00:00:02 |
|   2 |   UNION-ALL          |      |       |       |            |          |
|*  3 |    TABLE ACCESS FULL | T1   |  3083 |   475K|    31   (0)| 00:00:01 |
|*  4 |    FILTER            |      |       |       |            |          |
|*  5 |     TABLE ACCESS FULL| T2   |     5 |   790 |   12    (1)| 00:00:02 |
-----------------------------------------------------------------------------


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


   3 - filter("OBJECT_TYPE"='TABLE')
   4 - filter(NULL IS NOT NULL)
   5 - filter("OBJECT_TYPE"='TABLE')


奇怪的是:我們查的數(shù)據(jù)只在T1中存在根本不關(guān)T2的事!而且看filter4:NULL IS NOT NULL這個條件我們沒有指定,是履行計劃加的!
這個條件始終未FALSE。


繼續(xù),為了說明NOT NULL束縛是如何作用的再來看1個例子:
code3:
drop table t;
create table t
  as
  select * from all_objects;


create index t_idx on t(object_type);


exec dbms_stats.gather_table_stats( user, 'T' );


select count(*) from t;
Execution Plan
----------------------------------------
Plan hash value: 2966233522


-------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |   283   (1)| 00:00:04 |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| T    | 68437 |   283   (1)| 00:00:04 |
-------------------------------------------------------------------


這個計劃沒有使用我們創(chuàng)建的索引。緣由是object_type列是nullable,索引其實不包括所有NULL值,所以沒法根據(jù)索引鍵值進行
COUNT操作。如果我們告知數(shù)據(jù)庫:OBJECT_TYPE IS NOT NULL,履行計劃將立馬轉(zhuǎn)變!
code4:
alter table t modify object_type NOT NULL;
select count(*) from t;
Execution Plan
------------------------------------------
Plan hash value: 1058879072


------------------------------------------------------------------------
| Id  | Operation             | Name  | Rows   | Cost (%CPU)| Time     |
------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |       |     1  |    54   (2)| 00:00:01 |
|   1 |  SORT AGGREGATE       |       |     1  |            |          |
|   2 |   INDEX FAST FULL SCAN| T_IDX | 68437  |    54   (2)| 00:00:01 |
------------------------------------------------------------------------


some kind of 奇異吧!
問題是加入該object_type列可以為NULL,又該如何解決?答案是我們可以創(chuàng)建多列索引(組合索引)固然object_type比在其中。
例如:
code5:
drop index t_idx;
create index t_idx on t (object_type, 0);
code6:
select * from t where object_type is null;
Execution Plan
-----------------------------
Plan hash value: 470836197


--------------------------------------------------------------------------------------
| Id  | Operation                    | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |       |     1 |   101 |  1      (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID | T     |     1 |   101 |  1      (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN           | T_IDX |     1 |       |  1      (0)| 00:00:01 |
--------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("OBJECT_TYPE" IS NULL)
   


2、來看主外鍵束縛如何影響履行計劃:
code7:
drop table emp;
drop table dept;
drop view emp_dept;


create table emp
  as
  select *
  from scott.emp;


create table dept
  as
  select *
  from scott.dept;


create or replace view emp_dept
  as
  select emp.ename, dept.dname
    from emp, dept
   where emp.deptno = dept.deptno; 


--我們偽裝EMP和DEPT兩個表示大表!
begin
     dbms_stats.set_table_stats
         ( user, 'EMP', numrows=>1000000, numblks=>100000 );
     dbms_stats.set_table_stats
         ( user, 'DEPT', numrows=>100000, numblks=>10000 );
  end; 
  /
  
code8:
SQL> select ename from emp_dept;


Execution Plan
-----------------------------
Plan hash value: 615168685


----------------------------------------------------------------------------------------
| Id   | Operation          | Name  | Rows  |  Bytes |TempSpc | Cost (%CPU) | Time     |
----------------------------------------------------------------------------------------
|    0 | SELECT STATEMENT   |       |  1000K|     31M|        | 31515    (1)| 00:06:19 |
|*   1 |  HASH JOIN         |       |  1000K|     31M|   2448K| 31515    (1)| 00:06:19 |
|    2 |   TABLE ACCESS FULL| DEPT  |   100K|   1269K|        |  2716    (1)| 00:00:33 |
|    3 |   TABLE ACCESS FULL| EMP   |  1000K|     19M|        | 27151    (1)| 00:05:26 |
----------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")


此處我們只查詢EMP表的ename列,DEPT表現(xiàn)得沒啥必要。但是DEPTNO是DEPT表的主鍵,EMP表的外鍵!這樣就致使EMP表中DEPTNO列是非空的。但是我們沒有指明這層關(guān)系,
ORACLE自然不知道,所以我們這么做:
alter table dept add constraint dept_pk primary key(deptno);


alter table emp add constraint emp_fk_dept foreign key(deptno) references dept(deptno);


select ename from emp_dept;


Execution Plan
------------------------------
Plan hash value: 3956160932


--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      | 50000 |   976K| 27152   (1)| 00:05:26 |
|*  1 |  TABLE ACCESS FULL| EMP  | 50000 |   976K| 27152   (1)| 00:05:26 |
--------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("EMP"."DEPTNO" IS NOT NULL)


起作用了!加了個filter。
  
3、來看1個NOT NULL和主外鍵束縛搭配物化視圖查詢是如何影響履行計劃的
我常常把物化視圖作為”數(shù)據(jù)倉庫索引“使用,其最重要的用處是作為“preanswer”,將針對特定表的復(fù)雜和長時間運行的結(jié)果保存在1個永久表中。
說白了就是加速查詢速度。
alter table emp drop constraint emp_fk_dept;


alter table dept drop constraint dept_pk;


code10:
create materialized view mv enable query rewrite
  as
  select dept.deptno, dept.dname, count (*) from emp, dept
   where emp.deptno = dept.deptno
   group by dept.deptno, dept.dname;


begin
    dbms_stats.set_table_stats
    ( user, 'MV', numrows=>100000, numblks=>10000 );
end; 
/


code11: 1個查詢使用物化視圖
select dept.dname, count (*) from emp, dept
   where emp.deptno = dept.deptno and dept.dname = 'SALES'
   group by dept.dname; 


Execution Plan
------------------------------
Plan hash value: 1703036361


--------------------------------------------------------------------------------------------
| Id  | Operation                         | Name | Rows  |  Bytes| Cost (%CPU)  | Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |      |  1000 | 22000 |  2716     (1)| 00:00:33 |
|   1 |  SORT GROUP BY NOSORT             |      |  1000 | 22000 |  2716     (1)| 00:00:33 |
|*  2 |   MAT_VIEW REWRITE ACCESS FULL    | MV   |  1000 | 22000 |  2716     (1)| 00:00:33 |
--------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("MV"."DNAME"='SALES')


code12: 1個查詢沒有使用物化視圖
SQL> select count(*) from emp;


COUNT(*)
--------
      14


SQL> select * from table(dbms_xplan.display_cursor);


PLAN_TABLE_OUTPUT
-----------------------
SQL_ID  g59vz2u4cu404, child number 1
-----------------------
select count(*) from emp


Plan hash value: 2083865914


-------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |       | 27142 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |            |          |
|   2 |   TABLE ACCESS FULL| EMP  |  1000K| 27142   (1)| 00:05:26 |
-------------------------------------------------------------------
14 rows selected.




很明顯,更有的履行計劃應(yīng)當是查詢物化視圖中實現(xiàn)計算好的數(shù)據(jù)。
為此,我們需要告知數(shù)據(jù)庫以下內(nèi)容:
DEPTNO in DEPT is a primary key
DEPTNO in EMP is a foreign key
DEPTNO in EMP is a NOT NULL column


alter table dept add constraint dept_pk primary key(deptno);


alter table emp add constraint emp_fk_dept foreign key(deptno) references dept(deptno);


alter table emp modify deptno NOT NULL;


code13:
SQL> select count(*) from emp;


COUNT(*)
-------
     14


SQL> select * from table(dbms_xplan.display_cursor);


PLAN_TABLE_OUTPUT
-----------------------
SQL_ID  g59vz2u4cu404, child number 2
-----------------------
select count (*) from emp


Plan hash value: 1747602359


--------------------------------------------------------------------------------------
| Id  | Operation                     | Name | Rows |  Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |      |      |        |  2716 (100)|          |
|   1 |  SORT AGGREGATE               |      |    1 |     13 |            |          |
|   2 |   MAT_VIEW REWRITE ACCESS FULL| MV   |  100K|   1269K| 2716    (1)| 00:00:33 |
--------------------------------------------------------------------------------------




關(guān)于物化視圖的查詢重寫特性參考:http://blog.itpub.net/28719055/viewspace⑴258720/



-------------------------------

Dylan    Presents.









生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 精品国产一区二区三区成人影院 | 美女黄视频免费 | 国产高清精品一区二区三区 | 99久久精品免费看国产免费软件 | 日韩久久免费视频 | 黄色永久网站 | 日韩电影在线播放 | 精品二区 | 久久久久国产精品 | 亚洲视频免费观看 | a中文在线视频 | 日韩免费观看视频 | 精品国产一区二区三区在线观看 | 嫩草影院ncyy网址 | 欧美又大粗又爽又黄大片视频 | 色综合欧美 | h片在线观看免费 | 精品一区二区久久久久久久网站 | 亚洲精品黄色 | 99re久久 | 久久激情免费视频 | 久久av网| 天天干狠狠干 | 国内精品一区二区 | 日本在线中文 | 福利天堂 | 国产精品传媒麻豆hd | 国产乱码精品一区二区三区不卡 | 美女一区二区三区 | 久久久毛片 | 成人毛片网 | 欧美日韩一卡二卡 | 亚洲精品乱码久久久久久蜜桃图片 | 午夜在线免费观看视频 | 欧美精品一卡 | 国产一区二区三区在线观看免费 | 黄色的视频在线观看 | 99精品免费久久 | 国产高清不卡 | 欧美日韩色 | 精品91在线 |