Chinaunix首页 | 论坛 | 博客
  • 博客访问: 586446
  • 博文数量: 772
  • 博客积分: 5000
  • 博客等级: 大校
  • 技术积分: 4980
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-17 13:02
文章分类

全部博文(772)

文章存档

2011年(1)

2008年(771)

我的朋友

分类:

2008-10-17 13:22:53

   今天碰到了性能问题,DB Server 的 CPU 100%,vmstat 的输出也很高。找到 CPU 高的 sql 语句是使用了一个将 IP 地址字符串转换为数字的 PL/SQL 自定义函数,后来将这个逻辑放到数据库外的 VB 程序实现,CPU 使用率下降,问题解决。

    其实那个函数处理并不复杂,也没有访问数据库对象,没想到有如此大的影响。得出的结论就是:与数据库无关的处理过程放到数据库以外的调用程序来实现,即便用 sql 程序可以实现也应如此。

    还有一个要注意的问题,即不要在查询语句中调用自定义的 PL/SQL 函数,举个例子:

自定义函数如下,输入16位整数 IP 地址,输出 IP 所属省份,ipdb 中有8万条数据。
CREATE OR REPLACE FUNCTION fn_ipaddr_to_province (p_ipaddr NUMBER)
    
RETURN VARCHAR2
IS
    v_ret 
VARCHAR2 (100) := '';
BEGIN
    
BEGIN
        
SELECT province
            
INTO v_ret
            
FROM ipdb
        
WHERE start_ip <= p_ipaddr AND end_ip >= p_ipaddr AND ROWNUM = 1;
    EXCEPTION
        
WHEN NO_DATA_FOUND
        
THEN
            v_ret :
= '';
    
END;

    
RETURN v_ret;
EXCEPTION
    
WHEN OTHERS
    
THEN
        RAISE;
END fn_ipaddr_to_province;
/


根据省份确定地址,domainname 中有35条数据。

方法一:
...
BEGIN
    
SELECT serverip
        
INTO v_serverip
        
FROM domainname
    
WHERE province = fn_ipaddr_to_province (p_ip) AND ROWNUM = 1;
EXCEPTION
    
WHEN NO_DATA_FOUND
    
THEN
        v_serverip :
= 'mp3.u-vv.com';
END;
...


这种方法 CPU 使用率 90% 以上


方法二:
...
v_province :
= fn_ipaddr_to_province (p_ip);

BEGIN
    
SELECT serverip
        
INTO v_serverip
        
FROM domainname
    
WHERE province = v_province AND ROWNUM = 1;
EXCEPTION
    
WHEN NO_DATA_FOUND
    
THEN
        v_serverip :
= 'default domain';
END;
...


这种方法 CPU 使用率 40% 左右
【责编:Peng】

--------------------next---------------------

阅读(225) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~