- 浏览: 1026286 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (538)
- 奇文共赏 (36)
- spring (13)
- hibernate (10)
- AOP/Aspectj (9)
- spring security (7)
- lucence (5)
- compass (3)
- jbmp (2)
- jboss rule(drools) (0)
- birt (1)
- jasper (1)
- cxf (3)
- flex (98)
- webgis (6)
- 设计模式 (1)
- 代码重构 (2)
- log4j (1)
- tomcat (9)
- 神品音乐 (1)
- 工作计划 (2)
- appfuse (1)
- svn (4)
- 寻章摘句 (3)
- eclipse (10)
- arcgis api for flex (1)
- 算法 (5)
- opengis-cs (1)
- bug心得 (13)
- 图标 (1)
- software&key (14)
- java (17)
- 搞笑视频 (13)
- sqlserver (9)
- postgresql (1)
- postgis (0)
- geoserver (5)
- 日子 (50)
- 水晶报表 (1)
- 绝对电影 (3)
- Alternativa3D (1)
- 酷站大全 (10)
- c++ (5)
- oracle (17)
- oracle spatial (25)
- flashbuilder4 (3)
- TweenLite (1)
- DailyBuild (6)
- 华山论贱 (5)
- 系统性能 (5)
- 经典古文 (6)
- SOA/SCA/OSGI (6)
- jira (2)
- Hadoop生态圈(hadoop/hbase/pig/hive/zookeeper) (37)
- 风水 (1)
- linux操作基础 (17)
- 经济 (4)
- 茶 (3)
- JUnit (1)
- C# dotNet (1)
- netbeans (1)
- Java2D (1)
- QT4 (1)
- google Test/Mock/AutoTest (3)
- maven (1)
- 3d/OSG (1)
- Eclipse RCP (3)
- CUDA (1)
- Access control (0)
- http://linux.chinaunix.net/techdoc/beginner/2008/01/29/977725.shtml (1)
- redis (1)
最新评论
-
dove19900520:
朋友,你确定你的标题跟文章内容对应???
tomcat控制浏览器不缓存 -
wussrc:
我只想说牛逼,就我接触过的那点云计算的东西,仔细想想还真是这么 ...
别样解释云计算,太TM天才跨界了 -
hw_imxy:
endpoint="/Hello/messagebr ...
flex+java代码分两个工程 -
gaohejie:
rsrsdgrfdh坎坎坷坷
Flex 与 Spring 集成 -
李涤尘:
谢谢。不过说得有点太罗嗦了。
Oracle数据库数据的导入及导出(转)
http://www.oracle.com.cn/viewthread.php?tid=112596&highlight=%2Bwait4me
关于两个表关联进行更新,在论坛上经常有人问这个问题。尤其是不少刚刚从sql server转到oracle的
朋友,会把两种数据库的语法混淆。今天正好做了个测试,纪录下来
OS: RedHat Linus AS4
DB: Oracle 10gR2
案例:经典的detp/emp表,现在希望把emp.ename更新成ename+loc的形式。其中loc是通过关联emp和dept
取得的数据。
Last login: Mon Jan 22 15:40:57 2007 from 192.168.10.100
[oracle@testsrv1 ~]$ sqlplus /nolog
[uniread] Loaded history (3738 lines)
SQL*Plus: Release 10.2.0.1.0 - Production on Mon Jan 22 16:19:30 2007
Copyright (c) 1982, 2005, Oracle. All rights reserved.
idle> conn test/test
Connected.
准备数据的sql如下
复制内容到剪贴板
代码:
test@DW> !cat /tmp/pre.sql
drop table emp;
drop table dept;
CREATE TABLE dept (
deptno NUMBER(4),
dname VARCHAR2(14),
loc VARCHAR2(13));
CREATE TABLE emp (
empno NUMBER(4) ,
ename VARCHAR2(100),
job VARCHAR2(9),
mgr NUMBER(4),
sal NUMBER(7,2),
comm NUMBER(7,2),
deptno NUMBER(2)
);
insert into dept select * from scott.dept;
insert into emp select empno,ename,job,mgr,sal,comm,deptno from scott.emp;
commit;
exec dbms_stats.gather_table_stats(user,'DEPT',cascade=>true);
exec dbms_stats.gather_table_stats(user,'EMP',cascade=>true);
原始数据如下
test@DW> select * from emp;
EMPNO ENAME JOB MGR SAL COMM DEPTNO
---------- ---------- --------- ---------- ---------- ---------- ----------
7369 SMITH CLERK 7902 800 20
7499 ALLEN SALESMAN 7698 1600 300 30
7521 WARD SALESMAN 7698 1250 500 30
7566 JONES MANAGER 7839 2975 20
7654 MARTIN SALESMAN 7698 1250 1400 30
7698 BLAKE MANAGER 7839 2850 30
7782 CLARK MANAGER 7839 2450 10
7788 SCOTT ANALYST 7566 3000 20
7839 KING PRESIDENT 5000 10
7844 TURNER SALESMAN 7698 1500 0 30
7876 ADAMS CLERK 7788 1100 20
7900 JAMES CLERK 7698 950 30
7902 FORD ANALYST 7566 3000 20
7934 MILLER CLERK 7782 1300 10
14 rows selected.
test@DW> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
使用下面的语法(语法1)达到目的(注意,该语法有潜在的错误)
test@DW> update emp e set e.ename=e.ename ||'.'||(select d.loc from dept d where e.deptno=d.deptno);
test@DW> select * from emp;
EMPNO ENAME JOB MGR SAL COMM DEPTNO
---------- ------------------------------ --------- ---------- ---------- ---------- ----------
7369 SMITH.DALLAS CLERK 7902 800 20
7499 ALLEN.CHICAGO SALESMAN 7698 1600 300 30
7521 WARD.CHICAGO SALESMAN 7698 1250 500 30
7566 JONES.DALLAS MANAGER 7839 2975 20
7654 MARTIN.CHICAGO SALESMAN 7698 1250 1400 30
7698 BLAKE.CHICAGO MANAGER 7839 2850 30
7782 CLARK.NEW YORK MANAGER 7839 2450 10
7788 SCOTT.DALLAS ANALYST 7566 3000 20
7839 KING.NEW YORK PRESIDENT 5000 10
7844 TURNER.CHICAGO SALESMAN 7698 1500 0 30
7876 ADAMS.DALLAS CLERK 7788 1100 20
7900 JAMES.CHICAGO CLERK 7698 950 30
7902 FORD.DALLAS ANALYST 7566 3000 20
7934 MILLER.NEW YORK CLERK 7782 1300 10
14 rows selected.
test@DW> rollback;
Rollback complete.
为什么刚才说语法1有潜在的错误?因为在上面的例子中,两个表的关联部分没有unique属性,那么就可能出现一个
emp.deptno对应多个dept.deptno的情况。这里仅仅是可能出现,因为当这个情况出现的时候,大多是因为原始数据
中存在重复的,多余的数据。
那么,为了简单的避免上面的问题,我们使用语法2,加上一个max函数达到唯一的目的
test@DW> update emp e set e.ename=e.ename ||'.'||(select max(d.loc) from dept d where e.deptno=d.dep
tno);
14 rows updated.
test@DW> rollback;
test@DW> select * from emp;
EMPNO ENAME JOB MGR SAL COMM DEPTNO
---------- ------------------------------ --------- ---------- ---------- ---------- ----------
7369 SMITH.DALLAS CLERK 7902 800 20
7499 ALLEN.CHICAGO SALESMAN 7698 1600 300 30
7521 WARD.CHICAGO SALESMAN 7698 1250 500 30
7566 JONES.DALLAS MANAGER 7839 2975 20
7654 MARTIN.CHICAGO SALESMAN 7698 1250 1400 30
7698 BLAKE.CHICAGO MANAGER 7839 2850 30
7782 CLARK.NEW YORK MANAGER 7839 2450 10
7788 SCOTT.DALLAS ANALYST 7566 3000 20
7839 KING.NEW YORK PRESIDENT 5000 10
7844 TURNER.CHICAGO SALESMAN 7698 1500 0 30
7876 ADAMS.DALLAS CLERK 7788 1100 20
7900 JAMES.CHICAGO CLERK 7698 950 30
7902 FORD.DALLAS ANALYST 7566 3000 20
7934 MILLER.NEW YORK CLERK 7782 1300 10
14 rows selected.
test@DW> rollback;
Rollback complete.
在重复数据比较多的情况下,我们不想使用了聚合函数max,那么可以使用语法3,加入rownum=1条件
test@DW> update emp e set e.ename=e.ename ||'.'||(select d.loc from dept d where e.deptno=d.deptno a
nd rownum=1);
14 rows updated.
test@DW> select * from emp;
EMPNO ENAME JOB MGR SAL COMM DEPTNO
---------- ------------------------------ --------- ---------- ---------- ---------- ----------
7369 SMITH.DALLAS CLERK 7902 800 20
7499 ALLEN.CHICAGO SALESMAN 7698 1600 300 30
7521 WARD.CHICAGO SALESMAN 7698 1250 500 30
7566 JONES.DALLAS MANAGER 7839 2975 20
7654 MARTIN.CHICAGO SALESMAN 7698 1250 1400 30
7698 BLAKE.CHICAGO MANAGER 7839 2850 30
7782 CLARK.NEW YORK MANAGER 7839 2450 10
7788 SCOTT.DALLAS ANALYST 7566 3000 20
7839 KING.NEW YORK PRESIDENT 5000 10
7844 TURNER.CHICAGO SALESMAN 7698 1500 0 30
7876 ADAMS.DALLAS CLERK 7788 1100 20
7900 JAMES.CHICAGO CLERK 7698 950 30
7902 FORD.DALLAS ANALYST 7566 3000 20
7934 MILLER.NEW YORK CLERK 7782 1300 10
14 rows selected.
语法2和语法3有什么区别?我们来看看他们的执行计划
先看语法2
test@DW> explain plan for update emp e set e.ename=e.ename ||'.'||(select max(d.loc) from dept d whe
re e.deptno=d.deptno);
Explained.
test@DW> @/Oracle/product/10.2.1/rdbms/admin/utlxplp.sql
PLAN_TABLE_OUTPUT
--------------------
Plan hash value: 1667745622
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 14 | 126 | 3 (0)| 00:00:01 |
| 1 | UPDATE | EMP | | | | |
| 2 | TABLE ACCESS FULL | EMP | 14 | 126 | 3 (0)| 00:00:01 |
| 3 | SORT AGGREGATE | | 1 | 11 | | |
|* 4 | TABLE ACCESS FULL| DEPT | 1 | 11 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - filter("D"."DEPTNO"=:B1)
16 rows selected.
test@DW> rollback;
再来看看语法3
test@DW> explain plan for update emp e set e.ename=e.ename ||'.'||(select d.loc from dept d where e.
deptno=d.deptno and rownum=1);
Explained.
test@DW> @/Oracle/product/10.2.1/rdbms/admin/utlxplp.sql
PLAN_TABLE_OUTPUT
--------------------
Plan hash value: 764578432
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 14 | 126 | 3 (0)| 00:00:01 |
| 1 | UPDATE | EMP | | | | |
| 2 | TABLE ACCESS FULL | EMP | 14 | 126 | 3 (0)| 00:00:01 |
|* 3 | COUNT STOPKEY | | | | | |
|* 4 | TABLE ACCESS FULL| DEPT | 1 | 11 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter(ROWNUM=1)
4 - filter("D"."DEPTNO"=:B1)
17 rows selected.
仔细对比2和3的执行计划,他们唯一的区别在于:2使用了sort aggregate,而3使用了count stopkey
如果我们熟悉oracle分页算法,就知道count stopkey虽然名义上是全表扫描,但是在重复数据多的时候,会
根据指定的rownum=n在得到第n条纪录后停止扫描。而sort aggregate取得max,一定是执行全表扫描的。
通过这个细微的差别,我们可以判断出:当重复数据相对多的时候,使用rownum的语法3比语法2效率高(具体
高多少,这个需要实际测试)
===============================================================================
上面的讨论都是针对普通的表进行的,既没有任何约束条件的表关联。在实际操作中,我们更多情况面对的是
有主外键关系的表。那么,对我们的需求,又有了不同的解决方案
我们先给dept加上一个主键(实际上仅仅用唯一性约束就可以了)
test@DW> alter table dept add constraint pk_dept primary key (deptno);
或者直接使用唯一索引
test@DW> create unique index idx_dept on dept(deptno);
Table altered.
在现在的条件下,我们可以对视图(online view)直接进行更新操作。我们叫他语法4
test@DW> update (select ename,loc from emp,dept where emp.deptno=dept.deptno) v set v.ename=v.ename||'.'||v.loc;
14 rows updated.
在语法4中,我们先建立了一个online view,然后对她进行更新。一个包含多表的视图,是否可以更新,哪些字段
可以更新,涉及到一个叫 kep-preserved table的概念。简单的说,如果一个表的所有key同时也是视图的key,那么
这个表就是kep-preserved table。当视图中仅有一个kpt的时候,可以对kpt的数据进行更新操作。关于key-preseved
table和upatable columns的具体信息,请参考手册。
在我们的例子中,emp是key-preserved table,所以我们可以更新它的字段。
因为唯一索引,所以语法4的执行计划选择了使用索引,避免全表扫描
Execution Plan
----------------------------------------------------------
Plan hash value: 1686319074
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 14 | 280 | 4 (0)| 00:00:01 |
| 1 | UPDATE | EMP | | | | |
| 2 | NESTED LOOPS | | 14 | 280 | 4 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL | EMP | 14 | 126 | 3 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID| DEPT | 1 | 11 | 1 (0)| 00:00:01 |
|* 5 | INDEX UNIQUE SCAN | PK_DEPT | 1 | | 0 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")
总结:根据上面的分析,我个人给出的建议是:
1。如果满足updatable view的条件,优先使用语法4,更新onlien view
2。如果没有必要的约束条件,优先使用rownum
如果出现null之类的问题,请确保两张表之间的数据不存在a中有而b没有的
关于两个表关联进行更新,在论坛上经常有人问这个问题。尤其是不少刚刚从sql server转到oracle的
朋友,会把两种数据库的语法混淆。今天正好做了个测试,纪录下来
OS: RedHat Linus AS4
DB: Oracle 10gR2
案例:经典的detp/emp表,现在希望把emp.ename更新成ename+loc的形式。其中loc是通过关联emp和dept
取得的数据。
Last login: Mon Jan 22 15:40:57 2007 from 192.168.10.100
[oracle@testsrv1 ~]$ sqlplus /nolog
[uniread] Loaded history (3738 lines)
SQL*Plus: Release 10.2.0.1.0 - Production on Mon Jan 22 16:19:30 2007
Copyright (c) 1982, 2005, Oracle. All rights reserved.
idle> conn test/test
Connected.
准备数据的sql如下
复制内容到剪贴板
代码:
test@DW> !cat /tmp/pre.sql
drop table emp;
drop table dept;
CREATE TABLE dept (
deptno NUMBER(4),
dname VARCHAR2(14),
loc VARCHAR2(13));
CREATE TABLE emp (
empno NUMBER(4) ,
ename VARCHAR2(100),
job VARCHAR2(9),
mgr NUMBER(4),
sal NUMBER(7,2),
comm NUMBER(7,2),
deptno NUMBER(2)
);
insert into dept select * from scott.dept;
insert into emp select empno,ename,job,mgr,sal,comm,deptno from scott.emp;
commit;
exec dbms_stats.gather_table_stats(user,'DEPT',cascade=>true);
exec dbms_stats.gather_table_stats(user,'EMP',cascade=>true);
原始数据如下
test@DW> select * from emp;
EMPNO ENAME JOB MGR SAL COMM DEPTNO
---------- ---------- --------- ---------- ---------- ---------- ----------
7369 SMITH CLERK 7902 800 20
7499 ALLEN SALESMAN 7698 1600 300 30
7521 WARD SALESMAN 7698 1250 500 30
7566 JONES MANAGER 7839 2975 20
7654 MARTIN SALESMAN 7698 1250 1400 30
7698 BLAKE MANAGER 7839 2850 30
7782 CLARK MANAGER 7839 2450 10
7788 SCOTT ANALYST 7566 3000 20
7839 KING PRESIDENT 5000 10
7844 TURNER SALESMAN 7698 1500 0 30
7876 ADAMS CLERK 7788 1100 20
7900 JAMES CLERK 7698 950 30
7902 FORD ANALYST 7566 3000 20
7934 MILLER CLERK 7782 1300 10
14 rows selected.
test@DW> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
使用下面的语法(语法1)达到目的(注意,该语法有潜在的错误)
test@DW> update emp e set e.ename=e.ename ||'.'||(select d.loc from dept d where e.deptno=d.deptno);
test@DW> select * from emp;
EMPNO ENAME JOB MGR SAL COMM DEPTNO
---------- ------------------------------ --------- ---------- ---------- ---------- ----------
7369 SMITH.DALLAS CLERK 7902 800 20
7499 ALLEN.CHICAGO SALESMAN 7698 1600 300 30
7521 WARD.CHICAGO SALESMAN 7698 1250 500 30
7566 JONES.DALLAS MANAGER 7839 2975 20
7654 MARTIN.CHICAGO SALESMAN 7698 1250 1400 30
7698 BLAKE.CHICAGO MANAGER 7839 2850 30
7782 CLARK.NEW YORK MANAGER 7839 2450 10
7788 SCOTT.DALLAS ANALYST 7566 3000 20
7839 KING.NEW YORK PRESIDENT 5000 10
7844 TURNER.CHICAGO SALESMAN 7698 1500 0 30
7876 ADAMS.DALLAS CLERK 7788 1100 20
7900 JAMES.CHICAGO CLERK 7698 950 30
7902 FORD.DALLAS ANALYST 7566 3000 20
7934 MILLER.NEW YORK CLERK 7782 1300 10
14 rows selected.
test@DW> rollback;
Rollback complete.
为什么刚才说语法1有潜在的错误?因为在上面的例子中,两个表的关联部分没有unique属性,那么就可能出现一个
emp.deptno对应多个dept.deptno的情况。这里仅仅是可能出现,因为当这个情况出现的时候,大多是因为原始数据
中存在重复的,多余的数据。
那么,为了简单的避免上面的问题,我们使用语法2,加上一个max函数达到唯一的目的
test@DW> update emp e set e.ename=e.ename ||'.'||(select max(d.loc) from dept d where e.deptno=d.dep
tno);
14 rows updated.
test@DW> rollback;
test@DW> select * from emp;
EMPNO ENAME JOB MGR SAL COMM DEPTNO
---------- ------------------------------ --------- ---------- ---------- ---------- ----------
7369 SMITH.DALLAS CLERK 7902 800 20
7499 ALLEN.CHICAGO SALESMAN 7698 1600 300 30
7521 WARD.CHICAGO SALESMAN 7698 1250 500 30
7566 JONES.DALLAS MANAGER 7839 2975 20
7654 MARTIN.CHICAGO SALESMAN 7698 1250 1400 30
7698 BLAKE.CHICAGO MANAGER 7839 2850 30
7782 CLARK.NEW YORK MANAGER 7839 2450 10
7788 SCOTT.DALLAS ANALYST 7566 3000 20
7839 KING.NEW YORK PRESIDENT 5000 10
7844 TURNER.CHICAGO SALESMAN 7698 1500 0 30
7876 ADAMS.DALLAS CLERK 7788 1100 20
7900 JAMES.CHICAGO CLERK 7698 950 30
7902 FORD.DALLAS ANALYST 7566 3000 20
7934 MILLER.NEW YORK CLERK 7782 1300 10
14 rows selected.
test@DW> rollback;
Rollback complete.
在重复数据比较多的情况下,我们不想使用了聚合函数max,那么可以使用语法3,加入rownum=1条件
test@DW> update emp e set e.ename=e.ename ||'.'||(select d.loc from dept d where e.deptno=d.deptno a
nd rownum=1);
14 rows updated.
test@DW> select * from emp;
EMPNO ENAME JOB MGR SAL COMM DEPTNO
---------- ------------------------------ --------- ---------- ---------- ---------- ----------
7369 SMITH.DALLAS CLERK 7902 800 20
7499 ALLEN.CHICAGO SALESMAN 7698 1600 300 30
7521 WARD.CHICAGO SALESMAN 7698 1250 500 30
7566 JONES.DALLAS MANAGER 7839 2975 20
7654 MARTIN.CHICAGO SALESMAN 7698 1250 1400 30
7698 BLAKE.CHICAGO MANAGER 7839 2850 30
7782 CLARK.NEW YORK MANAGER 7839 2450 10
7788 SCOTT.DALLAS ANALYST 7566 3000 20
7839 KING.NEW YORK PRESIDENT 5000 10
7844 TURNER.CHICAGO SALESMAN 7698 1500 0 30
7876 ADAMS.DALLAS CLERK 7788 1100 20
7900 JAMES.CHICAGO CLERK 7698 950 30
7902 FORD.DALLAS ANALYST 7566 3000 20
7934 MILLER.NEW YORK CLERK 7782 1300 10
14 rows selected.
语法2和语法3有什么区别?我们来看看他们的执行计划
先看语法2
test@DW> explain plan for update emp e set e.ename=e.ename ||'.'||(select max(d.loc) from dept d whe
re e.deptno=d.deptno);
Explained.
test@DW> @/Oracle/product/10.2.1/rdbms/admin/utlxplp.sql
PLAN_TABLE_OUTPUT
--------------------
Plan hash value: 1667745622
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 14 | 126 | 3 (0)| 00:00:01 |
| 1 | UPDATE | EMP | | | | |
| 2 | TABLE ACCESS FULL | EMP | 14 | 126 | 3 (0)| 00:00:01 |
| 3 | SORT AGGREGATE | | 1 | 11 | | |
|* 4 | TABLE ACCESS FULL| DEPT | 1 | 11 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - filter("D"."DEPTNO"=:B1)
16 rows selected.
test@DW> rollback;
再来看看语法3
test@DW> explain plan for update emp e set e.ename=e.ename ||'.'||(select d.loc from dept d where e.
deptno=d.deptno and rownum=1);
Explained.
test@DW> @/Oracle/product/10.2.1/rdbms/admin/utlxplp.sql
PLAN_TABLE_OUTPUT
--------------------
Plan hash value: 764578432
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 14 | 126 | 3 (0)| 00:00:01 |
| 1 | UPDATE | EMP | | | | |
| 2 | TABLE ACCESS FULL | EMP | 14 | 126 | 3 (0)| 00:00:01 |
|* 3 | COUNT STOPKEY | | | | | |
|* 4 | TABLE ACCESS FULL| DEPT | 1 | 11 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter(ROWNUM=1)
4 - filter("D"."DEPTNO"=:B1)
17 rows selected.
仔细对比2和3的执行计划,他们唯一的区别在于:2使用了sort aggregate,而3使用了count stopkey
如果我们熟悉oracle分页算法,就知道count stopkey虽然名义上是全表扫描,但是在重复数据多的时候,会
根据指定的rownum=n在得到第n条纪录后停止扫描。而sort aggregate取得max,一定是执行全表扫描的。
通过这个细微的差别,我们可以判断出:当重复数据相对多的时候,使用rownum的语法3比语法2效率高(具体
高多少,这个需要实际测试)
===============================================================================
上面的讨论都是针对普通的表进行的,既没有任何约束条件的表关联。在实际操作中,我们更多情况面对的是
有主外键关系的表。那么,对我们的需求,又有了不同的解决方案
我们先给dept加上一个主键(实际上仅仅用唯一性约束就可以了)
test@DW> alter table dept add constraint pk_dept primary key (deptno);
或者直接使用唯一索引
test@DW> create unique index idx_dept on dept(deptno);
Table altered.
在现在的条件下,我们可以对视图(online view)直接进行更新操作。我们叫他语法4
test@DW> update (select ename,loc from emp,dept where emp.deptno=dept.deptno) v set v.ename=v.ename||'.'||v.loc;
14 rows updated.
在语法4中,我们先建立了一个online view,然后对她进行更新。一个包含多表的视图,是否可以更新,哪些字段
可以更新,涉及到一个叫 kep-preserved table的概念。简单的说,如果一个表的所有key同时也是视图的key,那么
这个表就是kep-preserved table。当视图中仅有一个kpt的时候,可以对kpt的数据进行更新操作。关于key-preseved
table和upatable columns的具体信息,请参考手册。
在我们的例子中,emp是key-preserved table,所以我们可以更新它的字段。
因为唯一索引,所以语法4的执行计划选择了使用索引,避免全表扫描
Execution Plan
----------------------------------------------------------
Plan hash value: 1686319074
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 14 | 280 | 4 (0)| 00:00:01 |
| 1 | UPDATE | EMP | | | | |
| 2 | NESTED LOOPS | | 14 | 280 | 4 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL | EMP | 14 | 126 | 3 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID| DEPT | 1 | 11 | 1 (0)| 00:00:01 |
|* 5 | INDEX UNIQUE SCAN | PK_DEPT | 1 | | 0 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")
总结:根据上面的分析,我个人给出的建议是:
1。如果满足updatable view的条件,优先使用语法4,更新onlien view
2。如果没有必要的约束条件,优先使用rownum
如果出现null之类的问题,请确保两张表之间的数据不存在a中有而b没有的
发表评论
-
oracle 连接数相关
2012-12-26 09:54 927http://www.ltesting.net/html/26 ... -
Oracle 数据库下 查询当前用户下所有表的记录总数
2010-03-30 14:03 1448select t.table_name,t.num_rows, ... -
详谈Oracle优化CPU使用率
2010-03-29 08:07 1854http://database.51cto.com/art/2 ... -
表之间插入数据
2010-03-03 16:26 1142insert into usersraw values() s ... -
Oracle SQL精妙SQL语句讲解
2009-11-22 20:08 1166http://space.itpub.net/219982/v ... -
ORACLE优化SQL语句,提高效率(3)
2009-11-22 20:05 1127http://space.itpub.net/?uid-219 ... -
ORACLE优化SQL语句,提高效率(2)
2009-11-22 20:05 1122http://space.itpub.net/?uid-219 ... -
ORACLE优化SQL语句,提高效率(1)
2009-11-22 20:04 1053http://space.itpub.net/?uid-219 ... -
"the account is locked"的解决方法
2009-08-31 21:11 1522用sys以sysdba的身份来进行登录,在sys状态是lo ... -
两个字段内容连接起来
2009-08-03 16:12 1168concat函数即可,如果是数字,他会变成字符串之后连接起来 ... -
如何在亿级记录表中创建索引
2009-03-30 14:46 1077http://ninedns.com/oracle/20074 ... -
Oracle数据导入导出imp/exp命令
2009-03-30 08:56 870http://www.cnblogs.com/jason_lb ... -
oracle大表分区的一点点心得
2009-03-25 08:01 2320http://www.knowsky.com/388420.h ... -
管理好ORACLE数据表的几个建议
2009-03-25 07:57 895http://oracle.chinaitlab.com/in ... -
oracle IMP 命令详解
2009-03-24 17:09 1576http://www.bokee.net/bloggermod ... -
Oracle数据库数据的导入及导出(转)
2009-03-24 16:05 1975Oracle数据库数据的导入 ...
相关推荐
给出了灰关联空间分解和灰色趋势关联分析的基本概念和方法 ,总结了用灰色趋势关联度进行系统分析的一般步骤 ,通过两个具体的实例研究分析了该方法的优越性和实用性.
对比分析法 数据分析 对比分析法:将两个或两个以上的数据进行对比分析,分析其中的差异,从而揭示这些事物发展变化的规律和情况。 横向比较: 指对同类的不同对象在统一标准下进行比较的方法。要注意事物的可比性...
近年来国内外学者对关联规则进行了大量的研究,为深入理解关联...其次从串行和并行两个角度总结了关联规则挖掘的一般方法,概述并分析了一些典型的关联规则挖掘模式;最后讨论了关联规则挖掘质量改善问题及领域应用。
1、面向对象分析中,一个事物发生变化会影响另一个事物,两个事物之间属于 ( )。 A、关联关系 B、依赖关系 C、实现关系 D、泛化关系 2、关于用例图中的参与者,说法正确的是( )。 A、参与者是与系统交互的事物,...
简单的一句话总结:一张表对应两张表。 1 实现多态关联 1.1 文章表的结构 public function up() { Schema::create('articles', function (Blueprint $table) { $table->increments('id'); $table->st
电商数据分析导论 1.3数据分析在电商中的应用 1 业务场景 2 3 CONTENTS 数据诊断及复盘 市场分析 4 竞争分析及渠道分析 5 活动及广告分析 6 产品分析及库存分析 7 消费者分析 业务场景 PART ONE 业 务 场 景 数据...
数据分析总结与感悟 数据分析总结与感悟 ⼩⽣今年研⼆,从事软件数据分析与挖掘不到两年。两年⾥⼩⽣忙忙碌碌,从来没有总结过⾃⼰的⼯作,今天暂停住忙碌的脚步,随意书写 ⼏⾏⽂字,权当忙⾥偷闲总结这两年数据...
微博ETL项目分析 一、数据格式 文件格式 Txt Csv’ Xls Doc ...将两个类别下各自对应的文件集,进行解析、结构化。 通过load语法,将数据分别导入到两张表当中。 三、主要思路与考点 主要思路 通过ja
6、方差分析(ANOVA/Analysis of Variance) 又称"变异数分析"或"F检验",是R.A.Fisher发明的,用于两个及两个以上样本均数差别的显著性检验。由于各种因素的影响,研究所得的数据呈现波动状。造成波动的原因可分成两...
关联分析:如果两个或多个事物之间存在一定的关联,那么其中一个事物就能通过其 他事物进行预测;它的目的是为了挖掘隐藏在数据间的相互关系; 4.因果分析:因果分析是为了确定引起某一现象变化原因的分析,主要解决...
主要介绍了Java实现把两个数组合并为一个的方法,结合实例形式总结分析了java常用的四种数组合并操作技巧,需要的朋友可以参考下
数据分析流程 关键数据: 客单价 客户满意度 用户回访率 投资回报率 独立用户访问量 积极访问者比率 忠实访问者比率 客户转化率 量化分析: 把两个相互联系的指标数据进行比较,从数量上展示和说明研究对象各种关系...
那影响应用市场排名的因素有哪些呢,不难查到,像应用的下载量、评价、星级等,那 在两个不同的时间点上到底发生了什么呢,去查一下应用对外的版本记录信息,信息不 是很多,但依然引起了我的注意: 比较可疑的是...
数据分析 19 交叉分析法 综合评价分析法 将两个有一定联系的变量及其值交 叉排在一张表内,即二维交叉表 将多个指标转化为一个能够反映综合 情况的指标进行评价 比如: Y=ax 1 +bx 2 +cx 3 +dx 4 +… 矩阵关联分法 ...
数据挖掘常用的方法: 利用数据挖掘进行数据分析常用的方法主要有分类、回归分析、聚类、关联规则、特征 、变化和偏差分析、Web页挖掘等, 它们分别从不同的角度对数据进行挖掘。 1、分类 分类是找出数据库中一组...
Spearman秩相关系数 不服从正态分布的变量,分类或等级变量之间的关联性可采用Spearman秩相关系数 总结上述两者: 只要两个变量具有严格单调的函数关系,那么他们一定是完全Spearman相关,Person相关只有在变量具有...
数据仓库和数据挖掘总结 38 4.1关联规则总结 38 4.2决策树总结 38 4.3聚类分析总结 40 第1章 数据仓库和数据挖掘简介 1.1数据简介 我的数据集是由两个不同的数据库组成,因为做关联规则的时候,影响小学生自控能 力...
五、数据挖掘任务 关联分析 两个或两个以上变量的取值之间存在某种规律性,就称为关联。数据关联是数据库中存在的⼀类重要的、可被发现的知识。关联分为简单关 联、时序关联和因果关联。关联分析的⽬的是找出数据库...
2.4 如何进行迭代和进化式分析和设计 2.5 什么是风险驱动和客户驱动的迭代计划 2.6 什么是敏捷方法及其观点 2.7 什么是敏捷建模 2.8 什么是敏捷UP .2.9 UP的其他关键实践 2.10 什么是UP的阶段 2.11 什么是UP...
2.4 如何进行迭代和进化式分析和设计 2.5 什么是风险驱动和客户驱动的迭代计划 2.6 什么是敏捷方法及其观点 2.7 什么是敏捷建模 2.8 什么是敏捷UP .2.9 UP的其他关键实践 2.10 什么是UP的阶段 2.11 什么是UP...