今天碰到了性能問(wèn)題,DB Server 的 CPU 100%,vmstat 的輸出也很高。找到 CPU 高的 sql 語(yǔ)句是使用了一個(gè)將 ip 地址字符串轉(zhuǎn)換為數(shù)字的 PL/SQL 自定義函數(shù),后來(lái)將這個(gè)邏輯放到數(shù)據(jù)庫(kù)外的 VB 程序?qū)崿F(xiàn),CPU 使用率下降,問(wèn)題解決。
自定義函數(shù)如下,輸入16位整數(shù) IP 地址,輸出 IP 所屬省份,ipdb 中有8萬(wàn)條數(shù)據(jù)。 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; /
根據(jù)省份確定服務(wù)器地址,domainname 中有35條數(shù)據(jù)。
方法一: ... 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; ...