首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 冲浪宝典 > 网络资源 > Oracle Advanced Sql
【标  题】:Oracle Advanced Sql
【关键字】:Oracle,Advanced,Sql
【来  源】:BLOG.CSDN.NET

Oracle Advanced Sql

ORACLE Advanced SQL

这篇文档对深入研究Oracle有很大的用处。下面分别从以下几个方面介绍。

Transaction Management,joins,Subquerys,Optimizer,Indexs, Enhancement to other SQL operations

如果您身边就有Oracle系统,那么您也可以通过运行本篇文章的例子来做一些试验。

l         事务处理(Transaction Management):

事务的四大特性原子性、隔离性、独立性,持续性。仅仅通过字面理解理解事务处理可能不是太直观。那么,我们可以借用Jim Gray的描述来理解——“ 事务概念是分布式计算的一个重要抽象。在某一个层次实现了事务,那么所有跟高层次上会有一个简化的失败语义(要么全做,要么全不做),并且错误处理也会简单得多。

Oracle中通过设置ISOLATION LEVEL来避免几乎所有数据库都可能遇到的问题——脏读(一个事务读取了另一个事务写的但是尚未提交的数据)、不一致分析(一个事务前后读取了不同的数据)和幻象数据读取(例如,我要执行一个事务查询,该事务查询的任务是查询13:00这个时间点的数据,但是这个事务执行时间可能需要一个小时,但是在这期间由于还有正常的数据操作。所以,当我在执行完事务查询时可能得到的数据就是14:00的数据了,我们称这种现象为幻象读取)。

我们知道标准的SQL99提出的事务隔离级别有四种,分别是READ UNCOMMITEDREAD COMMITEDREPEATABLE READSERIALIZABLEORACLE分别实现了READ COMMITEDSERIALIZABLE。从这一点当中我们可以看出,ORACLE默认是避免脏读的(当然这也不一定如果在执行完DML语句完以后如果没有做COMMIT操作可能也会出现脏读的情况。但是,我还没有遇到这种情况,读者可以自己试验。)例句 SET TRANSACTION ISOLATION LEVEL [READ COMMITED| SERIALIZABLE]READ COMMITED可以避免脏读,这也是ORACLE的默认选项。但是,它不可避免我们提出的不一致分析和幻象读取的问题。那么我们可以将其隔离级别设置为SERIALIZABLE这样我们就可以避免不一致分析和幻象读取的问题。那么,既然SERIALIZABLE级别这么好,那么我们是不是任何事务都要设置呢?答案是否定的,我们知道世界万物都是有其有利的一面就一定有其不利的一面。那么它的不利一面我们可以通过分析SERIALIZABLE的实现机制来看看。

从图中可以看出我们要实现SERIALIZABLE需要在系统中建立一个UNDO表空间来存放已经过时的数据。我们可以根据我们最大执行事务的执行时间来估算一个UNDO段的大小。显然,我们要是实现SERIALIZABLE就必须要另外的空间来建立UNDO表空间。也就是说我们要实现SERIALIZABLE是通过空间来换取避免不一致分析和幻象读取的。

l         Joins操作

在叙述下面的内容之前先介绍一下我的机器环境:

硬件环境:P4 2.8GMEMORY 526M,80G硬盘。

软件环境:Windows 2000,ORACLE 9.2.0.1

首先您要建立一个有足够量数据的表,我建立一个有100万行以上的数据的表

建表sql语句如下:

DROP SEQUENCE SEQ_EMP

/

CREATE SEQUENCE SEQ_EMP START WITH 1000000

/

DROP TABLE EMPLOYEE

/

CREATE TABLE EMPLOYEE

(EMPNO NUMBER(8),

 ENAME VARCHAR2(10),

 SAL   NUMBER(5),

 COMM  NUMBER(5),

 DEGREE NUMBER(1),

 HIREDATE DATE,

 DEPTNO NUMBER(2),

 ID_NO  VARCHAR2(18),

 BIRTHDAY DATE,

 CONSTRAINT PK_EMPLOYEE PRIMARY KEY(EMPNO)

)

/

CREATE OR REPLACE TRIGGER TRI_INS_EMPLOYEE

 BEFORE INSERT ON EMPLOYEE

 FOR EACH ROW

DECLARE

 V_EN EMPLOYEE.EMPNO%TYPE;

BEGIN

 V_EN:=:NEW.EMPNO;

 

  :NEW.COMM:=CEIL(:NEW.EMPNO/500000)*1000;

  :NEW.SAL:=(4-MOD(:NEW.EMPNO,4))*1000;

  :NEW.DEGREE:=CASE WHEN MOD(:NEW.EMPNO,4)=0 THEN NULL

                   WHEN MOD(:NEW.EMPNO,10)<7 THEN 1

                   WHEN MOD(:NEW.EMPNO,10)<9 THEN 2

                   ELSE 3

              END;

  :NEW.DEPTNO:=CASE WHEN :NEW.EMPNO<1000000 THEN 10

                    WHEN :NEW.EMPNO<1500000 THEN 20

                    WHEN :NEW.EMPNO<2000000 THEN 30

                    ELSE 40

               END;

  :NEW.ID_NO:=REPLACE('21010119'||(7+MOD(V_EN,3))||MOD(V_EN,10)||TO_CHAR(1+MOD(V_EN,12),'00')||TO_CHAR(MOD(V_EN,20)+1,'00')||0||TO_CHAR(MOD(V_EN,100),'00')||MOD(V_EN,2),' ',NULL);

 

  :NEW.ID_NO:=REPLACE(:NEW.ID_NO,' ',NULL);

 

 :NEW.BIRTHDAY:=TO_DATE(SUBSTR(:NEW.ID_NO,7,8),'YYYYMMDD');

END;

/

INSERT INTO EMPLOYEE (EMPNO)

 VALUES(SEQ_EMP.NEXTVAL)

/

/

INSERT INTO EMPLOYEE (EMPNO) (SELECT SEQ_EMP.NEXTVAL FROM EMPLOYEE)

/

    在做好以上准备以后我们就可以进行我们以后的实验了。

ORACLE中包括很多中连接方式EQUIJOINS SELF JOINS CARTESIAN PRODUCTS INNER JOINS OUTER JOINS ANTIJOINS SEMIJOINS

由于我的个人水平有限我不能全部介绍,我只能将自己理解的内容介绍个大家。

下面就仅仅介绍有关反连接的问题。

反连接(ANTIJOINS)通过 SET AUTOTRACE TRACE打开跟踪执行策略我们分别比较以下的语句。

============================================================

SELECT ENAME FROM EMP WHERE DEPTNO NOT IN(

   SELECT DEPTNO FROM DEPT WHERE LOC='NEW YORK');

 

SELECT ENAME FROM EMP WHERE NOT EXISTS(

   SELECT 1 FROM DEPT WHERE DEPT.DEPTNO=EMP.DEPTNO AND LOC='NEW YORK');

我们可以发现,运用NOT IN 要比 NOT EXISTS要快一些但是有个比较大的问题,就是在上面的实验中我们假设EMP表和DEPT表中没有字段内容为NULL的数据。如果我们要查询的表中有为NULL的数据的时候,那么我们在运用NOT IN操作会发现查出的数据是不准确的情况。结论:在您为选择NOT IN NOT EXISTS时而苦恼时请优先选择运用NOT EXISTS语句

接下来是有关JOIN的一些实验。

下面我们做如下试验

比较JOININ & 子查询以及EXISTS & 子查询 它们三者之间的执行效率

 

--12.04

SELECT * FROM EMPLOYEE A JOIN DEPT B ON A.DEPTNO=B.DEPTNO WHERE B.LOC='NEW YORK';

--4.02

SELECT * FROM EMPLOYEE WHERE DEPTNO IN (SELECT DEPTNO FROM DEPT WHERE LOC='NEW YORK');

--4.02

SELECT * FROM EMPLOYEE WHERE EXISTS (SELECT 1 FROM DEPT WHERE EMPLOYEE.DEPTNO=

       DEPT.DEPTNO AND LOC='NEW YORK');

 

通过上面的实验我们可以得出运用 IN或者 EXISTS操作的效率要高于运用JOIN操作的语句。我们知道ORACLE在执行用户的查询请求是ORACLE会选择一些查询策略来完成操作,但是有时候ORACLE的选择是很愚蠢的。比如,我要做一个简单的连接查询的操作SELECT * FROM EMPLOYEE A JOIN EMP B ON A.EMPNO=B.EMPNO;通过跟踪执行策略我们会发现ORACLE可能选择一个很慢的策略。那么,遇到这种情况该如何处理呢?我们可以通过两种方式来处理。第一,我们可以为该查询添加注释让它执行我们要求的策略。比如我们可以这么写SELECT /*+ use_rule…(EMPLOYEE EMP) */* FROM EMPLOYEE A JOIN EMP B ON A.EMPNO=B.EMPNO;(use_rule您可以选择您需要的策略。例如HASH JOIN等其他的执行策略)。例如,我们为上面这个查询语句选择下面两种策略:

1. SELECT /*+USE_HASH(EMPLOYEE,DEPT)*/* FROM EMPLOYEE,DEPT WHERE EMPLOYEE.DEPTNO=DEPT.DEPTNO;

2. SELECT /*+USE_MERGE(EMP,DEPT)*/* FROM EMP JOIN DEPT ON EMP.DEPTNO=DEPT.DEPTNO;

第二,就是,为该表添加统计资料分析信息ANALYZE TABLE EMPLOYEE COMPUTE STATISTICS;这样我们在对该表查询时ORACLE就可以选择一个较优的执行策略了。

通过以上的实验我们可以得出以下结论:ORACLE系统在执行DML语句的时候可能不会选择其最优的执行策略,这需要我们通过为DML语句添加注释强迫ORACLE选择一个我们人为指定的执行策略或者通过为表、试图等添加统计资料分析信息来使ORACLE在执行DML时选择较优的执行策略。

l         子查询(Subquery)

这部分内容我们将会做一系列的实验,最后我们从实验的结果当中得出使用子查询的情况。我并不是要介绍如何使用子查询,而是通过使用子查询来分析ORACLE的执行策略等信息。

实验1:比较JOININ以及EXISTS三种执行方式的执行时间

--12.04

SELECT * FROM EMPLOYEE A JOIN DEPT B ON A.DEPTNO=B.DEPTNO WHERE B.LOC='NEW YORK';

--4.02

SELECT * FROM EMPLOYEE WHERE DEPTNO IN (SELECT DEPTNO FROM DEPT WHERE LOC='NEW YORK');

--4.02

SELECT * FROM EMPLOYEE WHERE EXISTS (SELECT 1 FROM DEPT WHERE EMPLOYEE.DEPTNO=

              DEPT.DEPTNO AND LOC='NEW YORK');

 

通过实验1我们得出结论:使用EXISTSIN语句要比JOIN语句执行效率高。

调整对话框上控件布局的类CWindowMover:【上一篇】
Oracle初学者笔记(八)--Oracle中的对象(嵌套表与对象表):【下一篇】

【相关文章】
  • Windows Mobile 开发黄金周:Using SQL MOBILE on.NET CF 2.0 FAQ
  • Mysql与JSP网页中文乱码问题的解决方案
  • 关于Sql server中的DateAdd
  • E107系统resetcore.php模块 存在远程SQL注入漏洞
  • SQL Server数据库安全规划全攻略
  • 如何手动删除 SQL Server 2000 默认实例、命名实例或虚拟实例
  • Run Shark with MySQL
  • 如何缩小MSSQL中巨大的事务日志文件
  • 无聊的时候,写个sql,琢磨着解决自己工作中遇到的费时的问题.
  • 直接使用数据环境Close后再次open 导致表无效的解决方法!(VB6使用数据环境操作SQL时遇到问题)
  • 【随机文章】
  • sqlplus 常用命令
  • 2 Jive与设计模式2
  • 让Sqlite3以GB2312编码存储汉字
  • 建立指定日期范围的数组
  • JavaScript实用的一些技巧
  • 一些我常用的函数
  • select和option标签
  • JBuilder2005实战JSP之程序功能介绍(6)
  • 学习Emacs
  • JVM的生命周期
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.