博客首页 注册 建议与交流 排行榜 加入友情链接         宝宝相册的专门空间
推荐 投诉 搜索: 帮助

CLEANER

总觉得时间不够用,原来是自己把时间分散了。
   yuechaotian.cublog.cn
关于作者  
name:yuechaotian
employment:coder
age:25
from:NEU
about me:a retardate
email:yuechaotian(at)gmail.com
msn:yuechaotian(at)hotmail.com

我的分类  




今天遇到的 3个 Oracle 的问题
今天解决了3个 Oracle 的问题:
 
1. 重建 10g 控制台
 
 
2. EXP/IMP 的字符集问题
 
现场人员报告 DMP 文件导入 Oracle 后,存储过程的中文注释产生乱码,表、列的注释也是样。
 
这个 DMP 是从 Windows 上导出的,在 Linux 上导入时出现该问题。抓取的部分错误如下:

 

……

IMP-00003: ORACLE error 911 encountered

ORA-00911: invalid character

IMP-00017: following statement failed with ORACLE error 4043:

 "ALTER PROCEDURE "PRC_T_PERSON_ID_????" COMPILE REUSE SETTINGS TIMESTAMP '20"

 "07-05-14:18:29:36'"

IMP-00003: ORACLE error 4043 encountered

ORA-04043: object PRC_T_PERSON_ID_???? does not exist

About to enable constraints...

Import terminated successfully with warnings.

……

 

初步判断是字符集的问题。于是在两个数据库服务器上分别获取其字符集,发现二者相同,都是ZHS16GBK:

 

SQL> select userenv('language') from dual;

 

USERENV('LANGUAGE')

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

SIMPLIFIED CHINESE_CHINA.ZHS16GBK

 

那么查看各自的客户端字符集。从 Windows 的环境变量“HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOME0”里,看到 NLS_LAN 的设置也是 ZHS16GBK;而现场人员从 Linux 里获取到的客户端字符集为 UTF8。
 
问题就出在这里了,这个 DMP 是从 Windows 上导出的,然后在 Linux 上执行导入操作,由于客户端字符集不一致,导致出现乱码。
 
使用 Windows 做客户端重新执行导入操作,问题解决。
 
3. SQL优化
 
现场人员报告原来系统很好,从1.6.1版本升级到1.6.2后,核心业务变得很慢,慢到客户都没耐性等它做完,半小时后就直接关闭系统了。
 
从视图 v$session_wait 中获取该会话正处于 db file sequential read 等待。从 v$session.sql_address 中抓取 SQL 地址,然后从视图 v$sqlarea 中得到该SQL为:

 

update ac01 set akc023 = n_akc023 where aac001 = v_aac001;

 

当时觉得很奇怪,这个 SQL 怎么会产生等待呢?于是再通过如下 SQL 找到各个性能指标最高的执行 SQL:

  

SQL> SELECT MAX(DISK_READS) DISK_READS,

  2         MAX(BUFFER_GETS) BUFFER_GETS,

  3         MAX(ROWS_PROCESSED) ROWS_PROCESSED,

  4         MAX(EXECUTIONS) EXECUTIONS

  5    FROM V$SQLAREA;

 

DISK_READS BUFFER_GETS ROWS_PROCESSED EXECUTIONS

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

109547            36286762                      9020860           9020860

 

SQL> select sql_text from v$sqlarea where EXECUTIONS >= 9020860;

 

SQL_TEXT
---------------------------------------------------------

update ac01 set akc023 = n_akc023 where aac001 = v_aac001;

 

SQL>

 

执行次数(EXECUTIONS)最高的 SQL,居然还是这条简单的更新语句,而且 aac001 上建立了索引的。

 

查询系统的版本更新记录,发现开发人员这次就是更新了这个。那么问题基本就出在这里了。

 

查看编写的代码,发现该 SQL 是放在过程 A 的 FOR 循环里的,而过程 A 被另一个过程 B 调用。不幸的是,过程 A 又被放在了 B 的一个循环中,这是不应该的。

 

所以,一个7000人的单位,本来只需要更新7000次,现在却要更新 7000*7000 次。

 

修改一下业务逻辑就好了。

 

(上面的查询是从测试库获取的数据,生产库中,这个数值应该要大得多。)

 发表于: 2008-05-08,修改于: 2008-05-08 22:10 已浏览318次,有评论0条 推荐 投诉

  网友评论

  发表评论



Copyright © 2001-2006 ChinaUnix.net All Rights Reserved

感谢所有关心和支持过ChinaUnix的朋友们
页面生成时间:0.14754

京ICP证041476号