Oracle临时表 优化查询速度

oracle|临时表|速度|优化

1、前言
    目前所有使用Oracle作为数据库支撑平台的应用,大部分数据量比较庞大的系统,即表的数据量一般情况下都是在百万级以上的数据量。当然在Oracle中创建分区是一种不错的选择,但是当你发现你的应用有多张表关联的时候,并且这些表大部分都是比较庞大,而你关联的时候发现其中的某一张或者某几张表关联之后得到的结果集非常小并且查询得到这个结果集的速度非常快,那么这个时候我考虑在Oracle中创建“临时表”。
    我对临时表的理解:在Oracle中创建一张表,这个表不用于其他的什么功能,主要用于自己的软件系统一些特有功能才用的,而当你用完之后表中的数据就没用了。Oracle的临时表创建之后基本不占用表空间,如果你没有指定临时表(包括临时表的索引)存放的表空的时候,你插入到临时表的数据是存放在ORACLE系统的临时表空间中(TEMP)。
2、临时表的创建
    创建Oracle临时表,可以有两种类型的临时表:会话级的临时表和事务级的临时表。
    1)会话级的临时表因为这这个临时表中的数据和你的当前会话有关系,当你当前SESSION不退出的情况下,临时表中的数据就还存在,而当你退出当前SESSION的时候,临时表中的数据就全部没有了,当然这个时候你如果以另外一个SESSION登陆的时候是看不到另外一个SESSION中插入到临时表中的数据的。即两个不同的SESSION所插入的数据是互不相干的。当某一个SESSION退出之后临时表中的数据就被截断(truncate table,即数据清空)了。会话级的临时表创建方法:Create Global Temporary Table Table_Name(Col1 Type1,Col2 Type2...) On Commit Preserve Rows;举例create global temporary table Student(Stu_id Number(5),Class_id  Number(5),Stu_Name Varchar2(8),Stu_Memo varchar2(200)) on Commit Preserve Rows ;
    2)事务级临时表是指该临时表与事务相关,当进行事务提交或者事务回滚的时候,临时表中的数据将自行被截断,其他的内容和会话级的临时表的一致(包括退出SESSION的时候,事务级的临时表也会被自动截断)。事务级临时表的创建方法:Create Global Temporary Table Table_Name(Col1 Type1,Col2 Type2...) On Commit Delete Rows;举例:create global temporary table Classes(Class_id Number(5),Class_Name Varchar2(8),Class_Memo varchar2(200)) on Commit delete Rows ;
    3)、两种不通类型的临时表的区别:语法上,会话级临时表采用on commit preserve rows而事务级则采用on commit delete rows;用法上,会话级别只有当会话结束临时表中的数据才会被截断,而且事务级临时表则不管是commit、rollback或者是会话结束,临时表中的数据都将被截断。
3、例子:
    1)、会话级(Session关闭掉之后数据就没有了,当Commit的时候则数据还在,当Rollback的时候则数据也是一样被回滚):
     insert into student(stu_id,class_id,stu_name,stu_memo) values(1,1,'张三','福建');
     insert into student(stu_id,class_id,stu_name,stu_memo) values(2,1,'刘德华','福州');
     insert into student(stu_id,class_id,stu_name,stu_memo) values(3,2,'S.H.E','厦门');
SQL> select *from student ;

STU_ID CLASS_ID STU_NAME STU_MEMO
------ -------- -------- --------------------------------------------------------------------------------
     1        1 张三     福建
     2        1 刘德华   福州
     3        2 S.H.E    厦门
     4        2 张惠妹   厦门

SQL> commit;

Commit complete

SQL> select * from student ;

STU_ID CLASS_ID STU_NAME STU_MEMO
------ -------- -------- --------------------------------------------------------------------------------
     1        1 张三     福建
     2        1 刘德华   福州
     3        2 S.H.E    厦门
     4        2 张惠妹   厦门

SQL>insert into student(stu_id,class_id,stu_name,stu_memo) values(4,2,'张惠妹','厦门');

1 row inserted

SQL> select * from student ;

STU_ID CLASS_ID STU_NAME STU_MEMO
------ -------- -------- --------------------------------------------------------------------------------
     1        1 张三     福建
     2        1 刘德华   福州
     3        2 S.H.E    厦门
     4        2 张惠妹   厦门
     4        2 张惠妹   厦门

SQL> rollback ;

Rollback complete

SQL> select * from student ;

STU_ID CLASS_ID STU_NAME STU_MEMO
------ -------- -------- --------------------------------------------------------------------------------
     1        1 张三     福建
     2        1 刘德华   福州
     3        2 S.H.E    厦门
     4        2 张惠妹   厦门

SQL>
    2)、事务级(Commit之后就删除数据):本例子将采用以下的数据:
      insert into classes(Class_id,Class_Name,Class_Memo) values(1,'计算机','9608');
      insert into classes(Class_id,Class_Name,Class_Memo) values(2,'经济信息','9602');
      insert into classes(Class_id,Class_Name,Class_Memo) values(3,'经济信息','9603');
  在一个SESSION中(比如SQLPLUS登陆)插入上面3条记录,然后再以另外一个SESSION(用SQLPLUS再登陆一次)登陆,当你select * from classes;的时候,classes表是空的,而你再第一次登陆的SQLPLUS中select的时候可以查询到,这个时候你没有进行commit或者rollback之前你可以对刚才插入的3条记录进行update、delete等操作,当你进行commit或者rollback的时候,这个时候由于你的表是事务级的临时表,那么在插入数据的session也看不到数据了,这个时候数据就已经被截断了。
     运行结果如下:
SQL> insert into classes(Class_id,Class_Name,Class_Memo) values(1,'计算机','9608');

1 row inserted

SQL> insert into classes(Class_id,Class_Name,Class_Memo) values(2,'经济信息','9602');

1 row inserted

SQL> insert into classes(Class_id,Class_Name,Class_Memo) values(3,'经济信息','9603');

1 row inserted

SQL> update classes set class_memo ='' where class_id=3 ;

1 row updated

SQL> select * from classes ;

CLASS_ID CLASS_NAME CLASS_MEMO
-------- ---------- --------------------------------------------------------------------------------
       1 计算机     9608
       2 经济信息   9602
       3 经济信息  

SQL> delete from classes where class_id=3 ;

1 row deleted

SQL> select * from classes ;

CLASS_ID CLASS_NAME CLASS_MEMO
-------- ---------- --------------------------------------------------------------------------------
       1 计算机     9608
       2 经济信息   9602
SQL> commit;

Commit complete

SQL> select *from classes ;

CLASS_ID CLASS_NAME CLASS_MEMO
-------- ---------- --------------------------------------------------------------------------------

SQL>
再重复插入一次,然后rollback。
SQL> Rollback ;

Rollback complete

SQL> select * from classes ;

CLASS_ID CLASS_NAME CLASS_MEMO
-------- ---------- --------------------------------------------------------------------------------

SQL>

4、临时表的应用
    1)、当某一个SQL语句关联的表在2张及以上,并且和一些小表关联。可以采用将大表进行分拆并且得到比较小的结果集合存放在临时表中。
    2)、程序执行过程中可能需要存放一些临时的数据,这些数据在整个程序的会话过程中都需要用的等等。
5、注意事项:
    1)、临时表的索引以及对表的修改、删除等和正常的表是一致的。
    2)、Oracle的临时表是Oracle8i才支持的功能特性,如果你的Oracle版本比较低的话,那么就可能没有办法用到了,如果你的Oracle版本是8i的话,你还需要把$ORACLE_HOME/admin/${ORACLE_SID}/pfile目录下的init<ORACLE_SID>.ora初始参数配置文件的compatible修改为compatible = "8.1.0",我的服务器上就是这样子配置的。当然也可以修改为compatible = "8.1.6"

以上是我在对大表进行优化的时候采用的一些手段,效果显著。

时间: 2024-11-02 22:49:51

Oracle临时表 优化查询速度的相关文章

服务器-oracle千万级查询速度问题

问题描述 oracle千万级查询速度问题 一个2.3w的服务器,现有数据1500w左右,按月分区,大约有10几个分区. 查询两个一个上月的数据,查询时间在100s多,客户直接受不了了,是否可以秒开? 如何优化? 解决方案 为什么要一次性返回全部数据呢?那样当然慢,可以分页.另外,你是怎么查询的,有没有对条件加上索引. 解决方案二: 把一些常用数据放cache,内存中.查询数据库就刷新内存.这样只有第一个慢. 解决方案三: 你可以利用oracle的分批次查询,比如:SELECT * FROM (

Sql server2005 优化查询速度50个方法小结_mssql2005

I/O吞吐量小,形成了瓶颈效应. 没有创建计算列导致查询不优化. 内存不足. 网络速度慢. 查询出的数据量过大(可以采用多次查询,其他的方法降低数据量). 锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷). sp_lock,sp_who,活动的用户查看,原因是读写竞争资源. 返回了不必要的行和列. 查询语句不好,没有优化. 可以通过如下方法来优化查询 : 1.把数据.日志.索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持.数据量(

oracle查询速度会因具体的条件变慢

问题描述 oracle查询速度会因具体的条件变慢 select语句的结构完全一样,只是把其中一条where条件由='TCP14'改为='TCP17', 查询速度就由原来的瞬间变成3秒.我查看了TCP14下数据量和TCP17下数据量是差不多的. 请问原因和解决办法 解决方案 这个原因很多,cbo优化器根据代价来计算取最优的方式,你的这个问题可以把执行计划贴上来看看,原因的话很多可能,举个简单的,假如你的表存在10个数据块上,t14的数据存在前2个块上,而t17的数据分别存在第一个块,中间一个块,最

查询速度-mysql表字段select优化

问题描述 mysql表字段select优化 在一张表中,字段contentbody数据类型mediumtext,在contentbody中加 插入了大量的文字内容,如果在select查询过程中查询出contentbody, 则查询速度四五秒左右,非常慢,请问,有没有什么可优化 select contentbody from content这个sql的查询速度? 解决方案 建议你的select contentbody from content 后面增加where条件,只取需要的数据,或者根据需要分

oracle SQL优化到10人同时查询返回1s

问题描述 oracle SQL优化到10人同时查询返回1s 20C SELECT l.id l.pro_name l.pro_number s.qutt_financing_value s.qutt_project_deadline s.qutt_ready_rate s.qutt_cal_way NVL( (SELECT c.CUST_SIMPLENAME FROM T_CUST_COMPANY c WHERE c.id=l.assure_cust_id )'-') AS assure_nam

关于未来网站访问速度及后台查询速度的优化建议

1. 数据库设计:数据库内所有表结构均添加索引 调整原因: 近日数据库压力很大,经查有些大数据量表的查询速度很慢,导致数据库服务器CPU一直持续90%-100%,将这些表添加索引后,CPU很快变正常. 2. 将大数据表做分库.分区处理: 具体操作如下: 1).将大数据表与主数据库分离,单独新建一个数据库,然后将这些表做分区: 2).将数据插入到消息队列内,后台利用windows计划任务执行(5分钟执行一次)C#控制台程序将消息队列内的数据批量(消息队列内有50000条记录,一次性插入到数据表内)

请教:如何优化Datagridview的查询速度?

问题描述 有一个5000行左右的Datagridview数据,包括三列,一列代码,一列名称,一列备查的字符串,即代码+名称.象股票软件那样,每按一个字符查询一次,越来越精确地显示某一行或者某几行.目前的方法是修改Datagridview.Visible.曾经测试过,发现2000行以内的时候,查询速度还行,但达到5000行以后,实在太慢了.有什么样优化的办法吗?还是我设计程序的思路本来就不对,有更好的方法呢?请懂行的大侠不吝赐教.附程序如下:PrivateSubTextBox1_TextChang

oracle数据库优化

oracle|数据|数据库|优化 优化就是选择最有效的方法来执行SQL语句.Oracle优化器选择它认为最有效的 方法来执行SQL语句.   1).      IS NULL和IS NOT NULL 如果某列存在NULL值,即使对该列建立索引也不会提高性能. 2).      为不同的工作编写不同的SQL语句块 为完成不同的工作编写一大块SQL程序不是好方法.它往往导致每个任务的结果不优 化.若要SQL完成不同的工作,一般应编写不同的语句块比编写一个要好. 3).      IN 和EXISTS

Oracle中优化SQL的原则

oracle|优化 1.已经检验的语句和已在共享池中的语句之间要完全一样2.变量名称尽量一致3.合理使用外联接4.少用多层嵌套5.多用并发 语句的优化步骤一般有:1.调整sga区,使得sga区的是用最优.2.sql语句本身的优化,工具有explain,sql trace等3.数据库结构调整4.项目结构调整写语句的经验:1.对于大表的查询使用索引2.少用in,exist等3.使用集合运算 1.对于大表查询中的列应尽量避免进行诸如 To_char,to_date,to_number 等转换2.有索引