
作为一个Oracle数据库的用户 对于Export和Import两个命令绝对不会感到陌生 因为这二者正是我们经常用于数据备份和恢复的工具 但在使用这两个命令过程中所发生的Oracle字符集问题 常给一些Oracle使用者带来不必要的麻烦和不必要的数据损失 本文将就Export和Import过程中Oracle字符集的转换规律及使用这两个命令的注意事项做一总结 字符集转换的原因 Export Import过程如上图所示 从这个示意图中可以看到有四处关系到字符集 而这四处字符集的不一致恰恰是导致Oracle进行字符集转换的原因 源数据库字符集 Export过程中用户会话字符集 Import过程中用户会话字符集 目标数据库字符集 在Export和Import过程中 如果存在影响字符集转换的四因素不一致 则可能发生Oracle字符集转换 即 在Export过程中 如果源数据库字符集与Export用户会话字符集不一致 会发生字符集转换 并在导出的二进制格式Dmp文件的头部几个字节中存储Export用户会话字符集的ID号 在这个转换过程中可能发生数据的丢失 例 : 如果源数据库使用ZHS GBK 而Export用户会话字符集使用US ASCII 由于ZHS GBK是 位字符集 而US ASCII是 位字符集 这个转换过程中 中文字符在US ASCII中不能够找到对等的字符 所以所有中文字符都会丢失而变成 形式 即这种转换后生成的Dmp文件已经发生了数据丢失 例 : 如果源数据库使用ZHS GBK 而Export用户会话字符集使用ZHS CGB 但由于ZHS GBK字符集是ZHS CGB 字符集的超集 这个过程中绝大部分字符都能够正确转换 只有一些超出ZHS CGB 字符集的字符变为 形式 如果源数据库使用ZHS CGB 字符集 而Export用户会话使用ZHS GBK字符集 则转换过程能够完全转换成功 在Import向目标数据库转换过程中 其字符集发生转换的情况正好与Export过程相反 这里不再详述 在Export导出的Dmp文件中 含有Export用户会话字符集 在Import过程中 首先发生的是Dmp文件字符集(即Export用户会话字符集)向Import用户会话字符集的转换 如果这个转换过程不能正确完成 Import向目标数据库的导入过程也就不能完成 进行字符集的正确转换通常情况下 我们在使用Oracle的Export和Import过程中 并不希望发生字符的转换 但有时这种转换却是必要的 如我们在安装Oracle数据库时 选择ZHS CGB 字符集 由于这种字符集是一种中文小字符集 对于一些汉字不能够正确表示 这需要通过使用ZHS GBK字符集得到解决 此时就要进行字符集的转换 为了确保Export Import过程中 Oracle字符集不发生转换或正确转换 建议最好在进行这个过程前 检查一下源数据库字符集与Export用户会话字符集是否一致 源数据库字符集与目标数据库字符集是否一致 目标数据库字符与Import用户会话字符集是否一致 如果能够保证这四个字符集是一致的 则在Export Import过程中 Oracle字符集就不用发生转换 可用以下办法检查数据库字符集: 通过InitXXXX ora文件进行查看 借助SQL语句查看 SELECT NAME VALUE$ FROM SYS PROPS$ WHERE NAME= NLS_CHARACTERSET 对于Export Import用户会话字符集 在Windows系统中也可以通过注册表中的NLS_LANG进行查看或修改 对于Unix系统则可通过设置用户的环境变量NLS_LANG来查看或修改 特别要注意的是 Oracle数据库字符集通常是在创建时确定 一旦存储用户数据后就不要再修改了 因为其数据都是使用该字符集进行存储的 改换其他字符集之后 原有数据就不能够正确表示了 但如果确实想进行字符集改变 则可通过以下几步来实现 备份数据库后删除原数据(可物理备份 如使用Export 请注意确保字符集不发生转换或数据无损失) 使用Internal用户更新sys props$表中的字符集:Update sys props$ set name= Dest CharSet Where name= NLS_CHARACTERSET ; MIT; 重启数据库 恢复数据 下面字符集之间的转换是可行的 字符集子集向字符集父集转换是可行的 如ZHS CGB 向ZHS GBK转换 而字符集父类向字符集子集进行转换时 会损失部分数据 只包含英文字符数据的双字节字符集也可向单字节字符集转换 如ZHS GBK(English Only)可以向US ASCII正确转换 编码范围相同的单字节字符集之间通常可以进行相互转换 请注意 这里所说的没有数据损失 是指一种字符集A转换成另一种字符集B之后 可以再从字符集B正确转换成字符集A或字符集B能够正确表示字符集A中转换过来的数据 字符集对程序的影响根据一个字符需要多少位字节来表示 可以把字符集分为单字节字符集和多字节字符集 其中 单字节字符集又分为 位字符集和 位字符集 单字节 位编码字符集有US ASCⅡ 单字节 位编码字符集有符合ISO 标准规定的WE ISO P 等 多字节编码又分为固定长度(长度大于或等于 )编码模式和不固定长度编码模式 多字节编码字符集中的ZHS GBK ZHS CGB JA SJIS等是采用两个字节表示一个字符的字符集 又叫双字节字符集 一个英文字母是一个字符 一个中文汉字是几个字符呢?我们知道 一个中文汉字是双字节字符 但它有几个字符与其数据库字符集有关 如果数据库字符集使用单字节US ASCII 则一个中文汉字是二个字符 如果数据库字符集使用双字节字符集ZHS GBK 则一个中文汉字是一个字符 有关这一点可以使用Oracle的函数Substr得到证明 使用US ASCⅡ字符集时: Select substr( 东北大学 ) from dual; 语句执行结果返回 东 使用ZHS GBK字符集时: Select substr( 东北大学 ) from dual; 语句执行结果返回 东北 选择合适的数据库字符集选择数据库字符集时应考虑以下事项 .数据库需要支持什么语言 在为数据库选择字符集时 常会发现几种字符集都适合你当前语言需求 如简体中文就有ZHS GBK和ZHSCGB 等字符集可供选择 应选择哪种?在选择字符集时 应考虑到数据库将来的系统需求 如果知道将来数据库要扩展支持不同的语言 选择一个范围较广的字符集会是一个更好的主意 .系统资源与应用之间的互作用性选择的数据库字符集应保证 *** 作系统与应用之间的无缝连接 如果选择的字符集不是 *** 作系统有效的字符集 则系统就需要在这两者之间做字符转换 在这种字符转换过程中 就有可能发生一些字符丢失现象 从一种字符集A向另一种字符集B转换过程中 A中的字符必须在B中可以找到等价的字符 否则就会以 ? 来代替 从这个意义上说 如果两种字符集编码范围是相同的 则可以相互转换 字符集转换过程中会影响系统性能 因此 应保证客户端和服务器端有相同的字符集以避免字符集转换 也可以提高一定的系统性能 .系统的性能要求不同的数据库字符集对于数据库的性能是有一定影响的 为了得到最好的数据库性能 选择的数据库字符集应避免字符转换 并且要选择对于期望的语言有最高效的编码效率 通常 单字节字符集比多字节字符集有更优的性能表现 在空间需求方面也更小些 .其他一些限制在为数据库选择一个合适的字符集时 应参考Oracle对应版本的相关文档 检查Oracle对于一些字符集的限制 如Oracle 版本中 以下字符集是不能使用的: JA EUCFIXED ZHS GBKFIXED JA DBCSFIXED KO DBCSFIXED ZHS DBCSFIXED JA SJISFIXED ZHT TRISFIXED 综上所述 正确理解Oracle字符集的转换过程 可以使我们避免不必要的麻烦和数据损失 合理利用Oracle字符集的转换过程 也可以帮助我们正确地从一种字符集转换到另一种字符集 以满足我们各种不同的应用需求 lishixinzhi/Article/program/Oracle/201311/17956
一、如何查询session执行的历史sql语句
如何知道一个session都执行过哪些SQL语句?(查看当前比较容易,历史的呢?怎么复原sql的执行场景——事务关系、执行序列、单SQL还是存储过程)
方法一查询v$sqltext、v$sqlarea、v$sqlstats视图
select from v$sqlarea t where tPARSING_SCHEMA_NAME in ('schema') order by tLAST_ACTIVE_TIME desc;
#对v$sqltext、v$sqlarea查看的是shared pool中的SQL,其时间索引是其解析历史,因为共享的问题这个查询可能并不能完整地反映出执行的历史。
#v$sqlstats信息保留时间比v$sql、v$sqltext、v$sqlarea长,及时SQL已经换出shared pool仍然可查到
方法二
联合v$active_session_history和v$sqlarea
#v$active_session_history 这个表只是个取样数据,按秒进行,只有在那一秒采样点处于on cpu或非idle等待的session统计在内。所以可能会不全,有些执行很短的SQL会忽略。这个视图无法还原完整的session历史。
#v$sqlarea中有执行过的SQL语句,但并无到session的关联信息,v$session中只关联了当前的sql,所以也不行。
查看视图:dba_hist_sqlstats、dba_hist_sqltext(历史数据)
二、如何使用PL/SQL Developer查看和杀掉sessionoracle多用户 *** 作有时候会造成session阻塞,形成了锁表等问题。
可以使用sql语句进行查询,但用工具更为方便。本文就介绍使用PL/SQL developer工具查看或杀掉oracle的session。
工具/原料 PL/SQL Developer 版本为 8001480 方法/步骤 打开PL/SQL Developer,输入用户名密码和数据库等信息。 在工具栏中选择tools,在d出的窗口选择Sessions。
即可。 如图所示,所有的session和起sid都列了出来,我们需要找Status为active(活动)的。
点击一下即可,或者选择如图的下拉菜单,选择 Active sessions 如图,现在有两个活动的session,选择其中一个session后在下方可以查看此session的更多信息。 在SQL Text一栏中可以查看正在执行的sql语句。
在Locks一栏中,可以查看现在锁表等信息。 若要杀掉其中一个session,那么,对这个session一行点击右键,选择“kill”即可。
三、如何查看PL/SQL执行的历史除了PL/SQL的ctrl+e的查看方法外还有如下方法:方法一查询v$sql、v$sqltext、v$sqlarea、v$sqlstats视图select from v$sqlarea t where tPARSING_SCHEMA_NAME in ('schema') order by tLAST_ACTIVE_TIME desc;#对v$sqltext、v$sqlarea查看的是shared pool中的SQL,其时间索引是其解析历史,因为共享的问题这个查询可能并不能完整地反映出执行的历史。
#v$sqlstats反应的是实例启动起来的sql执行统计,sql语句本身比v$sqltext/area完整,因为后者有可能失效换出缓存。方法二联合v$active_session_history和v$sqlarea#v$active_session_history 这个表只是个取样数据,按秒进行,只有在那一秒采样点处于on cpu或非idle等待的session统计在内。
所以可能会不全,有些执行很短的SQL会忽略。这个视图无法还原完整的session历史。
#v$sqlarea中有执行过的SQL语句,但并无到session的关联信息,v$session中只关联了当前的sql,所以也不行。从v$sqlstat可以查看到数据库启动起来的所有SQL信息,但是没有时间顺序关系、没有执行用户信息,只有执行次数与资源统计。
从dba_hist_sqlstat可以看到AWR snapshot之间的SQL统计信息,与v$sqlstats比不受实例重启的影响,因为实例重启之后v$sqlstats中的信息就清除了。方法三:session traceSQL> execute dbms_sessionsession_trace_enable(true,true);PL/SQL procedure successfully pletedSQL> select count() from dba_hist_sqltext; COUNT()---------- 478SQL> select from V$sesstat where rownum=1; SID STATISTIC# VALUE---------- ---------- ---------- 134 0 1SQL> execute dbms_sessionsession_trace_disable;PL/SQL procedure successfully pleted$ cd $ORACLE_HOME/admin/test/udump$ ls -lrt$ tkprof test_ora_2195620trc reporttxt sys=no explain=no aggregate=yes$ more reporttxt --这个文件包括了启停trace之间所有SQL语句的执行信息,执行计划、统计方法四:logminer只包含DML与DDL语句,不能查询select语句。
另外需要开启supplemental logging,默认是没有开启的。conn / as sysdba--安装LOGMINERSQL> @$ORACLE_HOME/rdbms/admin/dbmslmdsql;SQL> @$ORACLE_HOME/rdbms/admin/dbmslmsql;SQL> @$ORACLE_HOME/rdbms/admin/dbmslmssql;SQL> @$ORACLE_HOME/rdbms/admin/prvtlmplb;--开启附加日志alter database add supplemental log data;--模拟DML *** 作conn p_chenming/。
SQL> select from test2;SQL> insert into test2 values(7,77);SQL> mit;conn / as sysdba--切归档SQL> alter system switch logfile;SQL> select name,dest_id,thread#,sequence# from v$archived_log; --最后一个即为新的归档--新建LOG MINERSQL> execute dbms_logmnradd_logfile(logfilename=>'/oracle/archive_10g/test/test_1_138_786808434arc',options=>dbms_logmnrnew); --开始minerSQL> execute dbms_logmnrstart_logmnr(options=>dbms_logmnrdict_from_online_catalog);--查看结果SQL> col username format a8;SQL> col sql_redo format a50 SQL> select username,s,timestamp,sql_redo from v$logmnr_contents where table_name='TEST2'; SQL> select username,s,timestamp,sql_redo from v$logmnr_contents where username='P_CHENMING'; --关闭MINERSQL> execute dbms_logmnrend_logmnr;--关闭辅助日志SQL> alter database drop supplemental log data;总结查看v$sqlarea只能查看粗略的历史,因为很多SQL是共享的。查看ASH也不全,因为这是采样数据,测试的时候基本没有把SQL查询出来。
查看V$SQLSTATS能看到所有执行过的sql,以及其执行统计,但是没有时序、没有用户信息。查看TRACE应该是最完整的,但需要在执行SQL前开启。
查看logminer不能查看select语句,而且默认的系统没有开启supplementing log,所以能查看的内容有限。或许还有审计的方法可用,我没测试。
每种方法都有各自的缺陷,看来很难有一种完备的查看SQL执行历史的方法。
四、如何查看PL/SQL执行的历史除了PL/SQL的ctrl+e的查看方法外还有如下方法:方法一查询v$sql、v$sqltext、v$sqlarea、v$sqlstats视图select from v$sqlarea t where tPARSING_SCHEMA_NAME in ('schema') order by tLAST_ACTIVE_TIME desc;#对v$sqltext、v$sqlarea查看的是shared pool中的SQL,其时间索引是其解析历史,因为共享的问题这个查询可能并不能完整地反映出执行的历史。
#v$sqlstats反应的是实例启动起来的sql执行统计,sql语句本身比v$sqltext/area完整,因为后者有可能失效换出缓存。方法二联合v$active_session_history和v$sqlarea#v$active_session_history 这个表只是个取样数据,按秒进行,只有在那一秒采样点处于on cpu或非idle等待的session统计在内。
所以可能会不全,有些执行很短的SQL会忽略。这个视图无法还原完整的session历史。
#v$sqlarea中有执行过的SQL语句,但并无到session的关联信息,v$session中只关联了当前的sql,所以也不行。从v$sqlstat可以查看到数据库启动起来的所有SQL信息,但是没有时间顺序关系、没有执行用户信息,只有执行次数与资源统计。
从dba_hist_sqlstat可以看到AWR snapshot之间的SQL统计信息,与v$sqlstats比不受实例重启的影响,因为实例重启之后v$sqlstats中的信息就清除了。方法三:session traceSQL> execute dbms_sessionsession_trace_enable(true,true);PL/SQL procedure successfully pletedSQL> select count() from dba_hist_sqltext; COUNT()---------- 478SQL> select from V$sesstat where rownum=1; SID STATISTIC# VALUE---------- ---------- ---------- 134 0 1SQL> execute dbms_sessionsession_trace_disable;PL/SQL procedure successfully pleted$ cd $ORACLE_HOME/admin/test/udump$ ls -lrt$ tkprof test_ora_2195620trc reporttxt sys=no explain=no aggregate=yes$ more reporttxt --这个文件包括了启停trace之间所有SQL语句的执行信息,执行计划、统计方法四:logminer只包含DML与DDL语句,不能查询select语句。
另外需要开启supplemental logging,默认是没有开启的。conn / as sysdba--安装LOGMINERSQL> @$ORACLE_HOME/rdbms/admin/dbmslmdsql;SQL> @$ORACLE_HOME/rdbms/admin/dbmslmsql;SQL> @$ORACLE_HOME/rdbms/admin/dbmslmssql;SQL> @$ORACLE_HOME/rdbms/admin/prvtlmplb;--开启附加日志alter database add supplemental log data;--模拟DML *** 作conn p_chenming/。
SQL> select from test2;SQL> insert into test2 values(7,77);SQL> mit;conn / as sysdba--切归档SQL> alter system switch logfile;SQL> select name,dest_id,thread#,sequence# from v$archived_log; --最后一个即为新的归档--新建LOG MINERSQL> execute dbms_logmnradd_logfile(logfilename=>'/oracle/archive_10g/test/test_1_138_786808434arc',options=>dbms_logmnrnew); --开始minerSQL> execute dbms_logmnrstart_logmnr(options=>dbms_logmnrdict_from_online_catalog);--查看结果SQL> col username format a8;SQL> col sql_redo format a50 SQL> select username,s,timestamp,sql_redo from v$logmnr_contents where table_name='TEST2'; SQL> select username,s,timestamp,sql_redo from v$logmnr_contents where username='P_CHENMING'; --关闭MINERSQL> execute dbms_logmnrend_logmnr;--关闭辅助日志SQL> alter database drop supplemental log data;总结查看v$sqlarea只能查看粗略的历史,因为很多SQL是共享的。查看ASH也不全,因为这是采样数据,测试的时候基本没有把SQL查询出来。
查看V$SQLSTATS能看到所有执行过的sql,以及其执行统计,但是没有时序、没有用户信息。查看TRACE应该是最完整的,但需要在执行SQL前开启。
查看logminer不能查看select语句,而且默认的系统没有开启supplementing log,所以能查看的内容有限。或许还有审计的方法可用,我没测试。
每种方法都有各自的缺陷,看来很难有一种完备的查看SQL执行历史的方法。
五、如何查看oracle中存储过程执行的历史记录select tsql_id,
tsql_text,
splan_hash_value,
soptimizer_cost,
sexecutions_total,
selapsed_time_total,
sdisk_reads_total,
sbuffer_gets_total
from DBA_HIST_SQLSTAT s, DBA_HIST_SQLTEXT t
where ssql_id=tsql_id
and tsql_text like'%存储过程名称%';
没有想到其他好办法,确实不太好查了,把存储过程当作SQL来查找吧。
六、oracle 中查询占用session最多的进程在故障发生时,尝试用下面的语句抓取数据库引起故障的点。
//在oracle中监控死锁//SELECT snusername, mSID, snSERIAL#, mTYPE, DECODE(mlmode, 0, 'None', 1, 'Null', 2, 'Row Share', 3, 'Row Excl', 4, 'Share', 5, 'S/Row Excl', 6, 'Exclusive', lmode, LTRIM(TO_CHAR(lmode, '990'))) lmode, DECODE(mrequest, 0, 'None', 1, 'Null', 2, 'Row Share', 3, 'Row Excl', 4, 'Share', 5, 'S/Row Excl', 6, 'Exclusive', request, LTRIM(TO_CHAR(mrequest, '990'))) request, mid1, mid2 FROM v$session sn, v$lock m WHERE (snSID = mSID AND mrequest != 0) --存在锁请求,即被阻塞 OR (snSID = mSID --不存在锁请求,但是锁定的对象被其他会话请求锁定 AND mrequest = 0 AND lmode != 4 AND (id1, id2) IN (SELECT sid1, sid2 FROM v$lock s WHERE request != 0 AND sid1 = mid1 AND sid2 = mid2)) ORDER BY id1, id2, mrequest; //定位引起oracle死锁的sql//select sql_text from v$sql where hash_value in (select sql_hash_value from v$session where sid in (select session_id from v$locked_object)) //下面的SQL查询可以用于确定锁住数据库对象的锁://select cowner, cobject_name, cobject_type, bsid, bserial#, bstatus, bosuser, bmachine from v$locked_object a , v$session b, dba_objects c where bsid = asession_id and aobject_id = cobject_id; //显示哪些会话被锁住/// showlocksql /COLUMN o_name format a10COLUMN lock_type format a20COLUMN object_name format a15SELECT RPAD (oracle_username, 10) o_name, session_id SID, DECODE (locked_mode, 0, 'None', 1, 'Null', 2, 'Row share', 3, 'Row Execlusive', 4, 'Share', 5, 'Share Row Exclusive', 6, 'Exclusive' ) lock_type, object_name, xidusn, xidslot, xidsqn FROM v$locked_object, all_objectsWHERE v$locked_objectobject_id = all_objectsobject_id;//显示所有的TM和TX锁/// showalllocksql /SELECT SID, TYPE, id1, id2, DECODE (lmode, 0, 'None', 1, 'Null', 2, 'Row share', 3, 'Row Exclusive', 4, 'Share', 5, 'Share Row Exclusive', 6, 'Exclusive' ) lock_type, request, ctime, BLOCK FROM v$lockWHERE TYPE IN ('TX', 'TM');// 在Oracle数据库中,可以通过kill session的方式来终止一个进程,其基本语法结构为: 被kill掉的session,状态会被标记为killed,Oracle会在该用户下一次touch时清除该进程我们发现当一个session被kill掉以后,该session的paddr被修改,如果有多个session被kill,那么多个session的paddr都被更改为相同的进程地址://alter system kill session 'sid,serial#' ; // 在oracle中kill掉的进程有时还需要等待pmon回滚数据库已经占有的资源有时候我们需要使用下面的脚本找出那些已经在oracle中kill掉的进程,在 *** 作系统中在kill一次//select paddr from v$process p where pid 1 minus select spaddr from v$session s;$ kill -9 &paddr。
1、调整数据结构的设计
这一部分在开发信息系统之前完成,程序员需要考虑是否使用ORACLE数据库的分区功能,对于经常访问的数据库表是否需要建立索引等。
2、调整应用程序结构设计
这一部分也是在开发信息系统之前完成,程序员在这一步需要考虑应用程序使用什么样的体系结构,是使用传统的Client/Server两层体系结构,还是使用Browser/Web/Database的三层体系结构。不同的应用程序体系结构要求的数据库资源是不同的。
3、调整数据库SQL语句
应用程序的执行最终将归结为数据库中的SQL语句执行,因此SQL语句的执行效率最终决定了ORACLE数据库的性能。ORACLE公司推荐使用ORACLE语句优化器(OracleOptimizer)和行锁管理器(row-levelmanager)来调整优化SQL语句。
4、调整服务器内存分配
内存分配是在信息系统运行过程中优化配置的,数据库管理员可以根据数据库运行状况调整数据库系统全局区(SGA区)的数据缓冲区、日志缓冲区和共享池的大小;还可以调整程序全局区(PGA区)的大小。需要注意的是,SGA区不是越大越好,SGA区过大会占用 *** 作系统使用的内存而引起虚拟内存的页面交换,这样反而会降低系统。
5、调整硬盘I/O
这一步是在信息系统开发之前完成的。数据库管理员可以将组成同一个表空间的数据文件放在不同的硬盘上,做到硬盘之间I/O负载均衡。
6、调整 *** 作系统参数
例如:运行在UNIX *** 作系统上的ORACLE数据库,可以调整UNIX数据缓冲池的大小,每个进程所能使用的内存大小等参数。
实际上,上述数据库优化措施之间是相互联系的。ORACLE数据库性能恶化表现基本上都是用户响应时间比较长,需要用户长时间的等待。但性能恶化的原因却是多种多样的,有时是多个因素共同造成了性能恶化的结果,这就需要数据库管理员有比较全面的计算机知识,能够敏感地察觉到影响数据库性能的主要原因所在。另外,良好的数据库管理工具对于优化数据库性能也是很重要的。
一、ORACLE数据库性能优化工具
常用的数据库性能优化工具有:
ORACLE数据库在线数据字典,ORACLE在线数据字典能够反映出ORACLE动态运行情况,对于调整数据库性能是很有帮助的。
*** 作系统工具,例如UNIX *** 作系统的vmstat,iostat等命令可以查看到系统系统级内存和硬盘I/O的使用情况,这些工具对于管理员弄清出系统瓶颈出现在什么地方有时候很有用。
SQL语言跟踪工具(SQLTRACEFACILITY),SQL语言跟踪工具可以记录SQL语句的执行情况,管理员可以使用虚拟表来调整实例,使用SQL语句跟踪文件调整应用程序性能。SQL语言跟踪工具将结果输出成一个 *** 作系统的文件,管理员可以使用TKPROF工具查看这些文件。
ORACLEEnterpriseManager(OEM),这是一个图形的用户管理界面,用户可以使用它方便地进行数据库管理而不必记住复杂的ORACLE数据库管理的命令。
EXPLAINPLAN——SQL语言优化命令,使用这个命令可以帮助程序员写出高效的SQL语言。
二、ORACLE数据库的系统性能评估
信息系统的类型不同,需要关注的数据库参数也是不同的。数据库管理员需要根据自己的信息系统的类型着重考虑不同的数据库参数。
1、在线事务处理信息系统(OLTP),这种类型的信息系统一般需要有大量的Insert、Update *** 作,典型的系统包括民航机票发售系统、银行储蓄系统等。OLTP系统需要保证数据库的并发性、可靠性和最终用户的速度,这类系统使用的ORACLE数据库需要主要考虑下述参数:
数据库回滚段是否足够
是否需要建立ORACLE数据库索引、聚集、散列
系统全局区(SGA)大小是否足够
SQL语句是否高效
2、数据仓库系统(DataWarehousing),这种信息系统的主要任务是从ORACLE的海量数据中进行查询,得到数据之间的某些规律。数据库管理员需要为这种类型的ORACLE数据库着重考虑下述参数:
是否采用B-索引或者bitmap索引
是否采用并行SQL查询以提高查询效率
是否采用PL/SQL函数编写存储过程
有必要的话,需要建立并行数据库提高数据库的查询效率
三、SQL语句的调整原则
SQL语言是一种灵活的语言,相同的功能可以使用不同的语句来实现,但是语句的执行效率是很不相同的。程序员可以使用EXPLAINPLAN语句来比较各种实现方案,并选出最优的实现方案。总得来讲,程序员写SQL语句需要满足考虑如下规则:
1、尽量使用索引。试比较下面两条SQL语句:
语句A:SELECTdname,deptnoFROMdeptWHEREdeptnoNOTIN
(SELECTdeptnoFROMemp);
语句B:SELECTdname,deptnoFROMdeptWHERENOTEXISTS
(SELECTdeptnoFROMempWHEREdeptdeptno=empdeptno);
这两条查询语句实现的结果是相同的,但是执行语句A的时候,ORACLE会对整个emp表进行扫描,没有使用建立在emp表上的deptno索引,执行语句B的时候,由于在子查询中使用了联合查询,ORACLE只是对emp表进行的部分数据扫描,并利用了deptno列的索引,所以语句B的效率要比语句A的效率高一些。
2、选择联合查询的联合次序。考虑下面的例子:
SELECTstuffFROMtabaa,tabbb,tabcc
WHEREaacolbetween:alowand:ahigh
ANDbbcolbetween:blowand:bhigh
ANDcccolbetween:clowand:chigh
ANDakey1=bkey1
AMDakey2=ckey2;
这个SQL例子中,程序员首先需要选择要查询的主表,因为主表要进行整个表数据的扫描,所以主表应该数据量最小,所以例子中表A的acol列的范围应该比表B和表C相应列的范围小。
3、在子查询中慎重使用IN或者NOTIN语句,使用where(NOT)exists的效果要好的多。
4、慎重使用视图的联合查询,尤其是比较复杂的视图之间的联合查询。一般对视图的查询最好都分解为对数据表的直接查询效果要好一些。
5、可以在参数文件中设置SHARED_POOL_RESERVED_SIZE参数,这个参数在SGA共享池中保留一个连续的内存空间,连续的内存空间有益于存放大的SQL程序包。
6、ORACLE公司提供的DBMS_SHARED_POOL程序可以帮助程序员将某些经常使用的存储过程“钉”在SQL区中而不被换出内存,程序员对于经常使用并且占用内存很多的存储过程“钉”到内存中有利于提高最终用户的响应时间。
四、CPU参数的调整
CPU是服务器的一项重要资源,服务器良好的工作状态是在工作高峰时CPU的使用率在90%以上。如果空闲时间CPU使用率就在90%以上,说明服务器缺乏CPU资源,如果工作高峰时CPU使用率仍然很低,说明服务器CPU资源还比较富余。
使用 *** 作相同命令可以看到CPU的使用情况,一般UNIX *** 作系统的服务器,可以使用sar_u命令查看CPU的使用率,NT *** 作系统的服务器,可以使用NT的性能管理器来查看CPU的使用率。
数据库管理员可以通过查看v$sysstat数据字典中“CPUusedbythissession”统计项得知ORACLE数据库使用的CPU时间,查看“OSUserlevelCPUtime”统计项得知 *** 作系统用户态下的CPU时间,查看“OSSystemcallCPUtime”统计项得知 *** 作系统系统态下的CPU时间, *** 作系统总的CPU时间就是用户态和系统态时间之和,如果ORACLE数据库使用的CPU时间占 *** 作系统总的CPU时间90%以上,说明服务器CPU基本上被ORACLE数据库使用着,这是合理,反之,说明服务器CPU被其它程序占用过多,ORACLE数据库无法得到更多的CPU时间。
数据库管理员还可以通过查看v$sesstat数据字典来获得当前连接ORACLE数据库各个会话占用的CPU时间,从而得知什么会话耗用服务器CPU比较多。
出现CPU资源不足的情况是很多的:SQL语句的重解析、低效率的SQL语句、锁冲突都会引起CPU资源不足。
1、数据库管理员可以执行下述语句来查看SQL语句的解析情况:
SELECTFROMV$SYSSTATWHERENAMEIN
('parsetimecpu','parsetimeelapsed','parsecount(hard)');
这里parsetimecpu是系统服务时间,parsetimeelapsed是响应时间,用户等待时间,waitetime=parsetimeelapsed_parsetimecpu
由此可以得到用户SQL语句平均解析等待时间=waitetime/parsecount。这个平均等待时间应该接近于0,如果平均解析等待时间过长,数据库管理员可以通过下述语句
SELECTSQL_TEXT,PARSE_CALLS,EXECUTIONSFROMV$SQLAREA
ORDERBYPARSE_CALLS;
来发现是什么SQL语句解析效率比较低。程序员可以优化这些语句,或者增加ORACLE参数SESSION_CACHED_CURSORS的值。
2、数据库管理员还可以通过下述语句:
SELECTBUFFER_GETS,EXECUTIONS,SQL_TEXTFROMV$SQLAREA;
查看低效率的SQL语句,优化这些语句也有助于提高CPU的利用率。
3、数据库管理员可以通过v$system_event数据字典中的“latchfree”统计项查看ORACLE数据库的冲突情况,如果没有冲突的话,latchfree查询出来没有结果。如果冲突太大的话,数据库管理员可以降低spin_count参数值,来消除高的CPU使用率。
五、内存参数的调整
内存参数的调整主要是指ORACLE数据库的系统全局区(SGA)的调整。SGA主要由三部分构成:共享池、数据缓冲区、日志缓冲区。
1、共享池由两部分构成:共享SQL区和数据字典缓冲区,共享SQL区是存放用户SQL命令的区域,数据字典缓冲区存放数据库运行的动态信息。数据库管理员通过执行下述语句:
select(sum(pins-reloads))/sum(pins)"LibCache"fromv$librarycache;
来查看共享SQL区的使用率。这个使用率应该在90%以上,否则需要增加共享池的大小。数据库管理员还可以执行下述语句:
select(sum(gets-getmisses-usage-fixed))/sum(gets)"RowCache"fromv$rowcache;
查看数据字典缓冲区的使用率,这个使用率也应该在90%以上,否则需要增加共享池的大小。
2、数据缓冲区。数据库管理员可以通过下述语句:
SELECTname,valueFROMv$sysstatWHEREnameIN('dbblockgets','consistentgets','physicalreads');
来查看数据库数据缓冲区的使用情况。查询出来的结果可以计算出来数据缓冲区的使用命中率=1-(physicalreads/(dbblockgets+consistentgets))。
这个命中率应该在90%以上,否则需要增加数据缓冲区的大小。
3、日志缓冲区。数据库管理员可以通过执行下述语句:
selectname,valuefromv$sysstatwherenamein('redoentries','redologspacerequests');
查看日志缓冲区的使用情况。查询出的结果可以计算出日志缓冲区的申请失败率:
申请失败率=requests/entries,申请失败率应该接近于0,否则说明日志缓冲区开设太小,需要增加ORACLE数据库的日志缓冲区。
昌平北大青鸟java培训班转载自网络如有侵权请联系我们感谢您的关注谢谢支持
设置ORACLE的会话连接超时:
1、profile的idle_time限制
oracle用户的配置文件的密码策略是实时生效的,所见即所得。但是用户配置文件的资源限制是由resource_limit参数决定的。
单位是分钟,默认没记错的话应该是10分钟
要是修改的资源生效,需要设置resource_limit设置为true
alter system set resource_limit=true ;
如果在idle的时间内用户没有执行任何 *** 作,会提示ORA-02396:exceeded maximum idle time, please connect again
2、profile的connect_time限制
默认是UNLIMITED,单位是分钟
用户在到达设置的时候后,不可以在继续 *** 作,会提示ORA-02399: exceeded maximum connect time, you are being logged off
如果是设置1分钟,他会在将近2分钟的时候提醒你重新登录。
3、sqlnet的expire_time限制:
expire_time主要是在指定的时间去探测客户端是否可以连通,如果可以的话重新计时,否则就会断开
在执行rman的时候遇见:ORA-03135: connection lost contact,可以尝试将此值设置大些。(ID 7298111)
4、sqlnet的inbound_connect_timieout_listener_name限制
单位是秒,默认值是60
以上就是关于Oracle在数据转储时的字符集问题全部的内容,包括:Oracle在数据转储时的字符集问题、oracle查看历史session、数据库性能优化有哪些措施等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)