下面是系统中用的非常频繁的一个函数,用来产生一个唯一码。
现在在做高压力测试的时候发现这块东西消耗了很多数据库的操作时间。程序中调用这个函数的点也很多,主要通过两种方式来获取这个唯一码
1.select fun_getid as id from dual;
2.在做insert时直接使用,如:insert into test(id,name) values (fun_getid,"test");
使用的oracle版本为10gcreate or replace function FUN_GETID return char is
  c_id  char(14);
begin
  select to_char(sysdate,'yyyymmdd')||trim(to_char(seq_id.nextval, '000000')) into c_id from dual;
  return  c_id;
end FUN_GETID;
create sequence SEQ_ID
minvalue 1
maxvalue 999999
start with 1
increment by 1
cache 20
cycle;
请大家看一下,这个函数是否存在什么问题,有优化的余地吗?
谢谢。

解决方案 »

  1.   

    为什么要select
    return  to_char(sysdate,'yyyymmdd')||trim(to_char(seq_id.nextval, '000000')) ;
    看看
      

  2.   

    必须要select,因为有seq_id.nextval。
      

  3.   

    如果这个函数调用很频繁,试试加大sequence的cache值,如加到10000
      

  4.   

    oracle也有用来产生唯一码的函数:
    SQL> select sys_guid() from dual;SYS_GUID()
    --------------------------------
    0573C33868404257ABE7D39488015D4D
      

  5.   

    这个语句没看出来有啥能优化的,只是有个建议,SEQUENCE可以一次生成多个序列,比如20个,然后每次在内存取,没有了才去生成新的
      

  6.   


    谢谢。
    这个cache是做了的cache 20
      

  7.   

    trim(to_char(seq_id.nextval, '000000')) 
    变成
    lpad(seq_id.nextval,6,'0')貌似会好一点点。
      

  8.   

    下面是我请教到的一个测试方法(给位看是否有问题)
    create or replace function fun_getid_trim return char is
      c_id  char(14);
    begin
      select to_char(sysdate,'yyyymmdd')||trim(to_char(seq_id.nextval, '000000')) into c_id from dual;
      return  c_id;
    end fun_getid_trim;
    create or replace function fun_getid_lpad return char is
      c_id  char(14);
    begin
      select to_char(sysdate,'yyyymmdd')||lpad(seq_id.nextval,6,0) into c_id from dual;
      return  c_id;
    end fun_getid_lpad;
    create or replace procedure testn2b
    as
      lt  number := dbms_utility.get_time;
      y number;
    begin
    lt  := dbms_utility.get_time;
    select fun_getid_lpad into y from dual where rownum <2 connect by level<=32768;
      lt := (dbms_utility.get_time - lt) ;
      dbms_output.put_line('fun_getid_lpad Times: ' ||
                           to_char(to_date(to_char(lt, 'fm00000'), 'sssss'),
                                   'hh24:mi:ss'));
    lt  := dbms_utility.get_time;
    select fun_getid_trim into y from dual where rownum <2 connect by level<=32768;
      lt := (dbms_utility.get_time - lt) ;
      dbms_output.put_line('fun_getid_trim Times: ' ||
                           to_char(to_date(to_char(lt, 'fm00000'), 'sssss'),
                                   'hh24:mi:ss'));
    end;这个是测试的结果SQL> exec testn2b;fun_getid_lpad Times: 00:00:03
    fun_getid_trim Times: 00:00:03
      

  9.   

    在我这里,多次执行的结果是:
    SQL>select max(rt) from (select lpad(level,6,'0') rt from dual connect by level <=1000000);
    経過: 00:00:01.95
    SQL>select max(rt) from (select trim(to_char(level,'000000')) rt from dual connect by level <=1000000);
    経過: 00:00:02.25
    可见这种函数之间的差异是很小的,100万条只是一点点地不同。