select dbo.fun(icode) nid from t
dbo.fun是自定义函数,表t有上千条数据,结果超时,是因为执行了函数才超时的,
请问该如何解决?
函数如下:
ALTER                FUNCTION fun
(
@icode nvarchar(30)
)
RETURNS int
 AS  
BEGIN 
    declare @tb table(nid int identity(1,1),icode nvarchar(30),OneMonthPer decimal(18,4))
    insert into @tb select icode,OneMonthPer from NT_Insurance_NetVTbl order by OneMonthPer desc
    declare @nid int,@nid2 float,@count int
    select @count=count(*) from @tb
    select @nid=nid from @tb where icode=@icode
    set @nid2=cast(@nid as float)/(@count/10)
    if(@nid2<=1)       return 1
    else if(@nid2<=2)  return 2
    else if(@nid2<=3)  return 3
    else if(@nid2<=4)  return 4
    else if(@nid2<=5)  return 5
    else if(@nid2<=6)  return 6
    else if(@nid2<=7)  return 7
    else if(@nid2<=8)  return 8
    else if(@nid2<=9)  return 9
    else if(@nid2<=10) return 10    return 1
END

解决方案 »

  1.   

    NT_Insurance_NetVTbl 里数据量很大?
      

  2.   

    try
    --select dbo.fun(icode) nid from t 
    ALTER   FUNCTION fun 

    @icode nvarchar(30) 

    RETURNS int 
    AS  
    BEGIN 
        --declare @tb table(nid int identity(1,1),icode nvarchar(30),OneMonthPer decimal(18,4)) 
        --insert into @tb select icode,OneMonthPer from NT_Insurance_NetVTbl order by OneMonthPer desc 
        declare @nid int,@nid2 float,@count int     --select @count=count(*) from @tb 
    select @count=count(*) from NT_Insurance_NetVTbl  --不需要零时表
     
    --    select @nid=nid from @tb where icode=@icode 
    select @nid=nid from NT_Insurance_NetVTbl where icode=@icode --不需要零时表
        set @nid2=cast(@nid as float)/(@count/10) 
        if(@nid2 <=1)      return 1 
        else if(@nid2 <=2)  return 2 
        else if(@nid2 <=3)  return 3 
        else if(@nid2 <=4)  return 4 
        else if(@nid2 <=5)  return 5 
        else if(@nid2 <=6)  return 6 
        else if(@nid2 <=7)  return 7 
        else if(@nid2 <=8)  return 8 
        else if(@nid2 <=9)  return 9 
        else if(@nid2 <=10) return 10     return 1 
    END
      

  3.   

    1.将以下两句放在函数外一次执行,形成永久表
        declare @tb table(nid int identity(1,1),icode nvarchar(30),OneMonthPer decimal(18,4)) 
        insert into @tb select icode,OneMonthPer from NT_Insurance_NetVTbl order by OneMonthPer desc 
    2.将这个总数作为函数的一个参数传放
        select @count=count(*) from @tb 
      

  4.   

     icode,OneMonthPer 建联合索引
      

  5.   

    --try
    ALTER FUNCTION fun 

    @icode nvarchar(30) 

    RETURNS int 
    AS  
    BEGIN 
        declare @nid int,@nid2 float,@count int 
        select @count=count(*) from NT_Insurance_NetVTbl 
        select @nid=count(*) from NT_Insurance_NetVTbl 
    where OneMonthPer>=(select OneMonthPer from NT_Insurance_NetVTbl where icode=@icode) 
        
    return ceiling(@nid*10.0/@count)     
    END
      

  6.   

    回老高,去小表变量,NT_Insurance_NetVTbl没有nid字段作为排序数,NT_Insurance_NetVTbl数据量几十万
    回树上的鸟儿,用永久表是否会不灵活?
      

  7.   

    select dbo.fun(icode) nid from t 
    你这个都没有筛选条件,可以直接在函数里返回一个表,,,
      

  8.   


    不要用function了,NT_Insurance_NetVTbl里数据量这么大,还是先按照icode做成合适的数据集,再 和t表连接处理,要不然执行一次函数就要查询NT_Insurance_NetVTbl,不慢才怪
      

  9.   

    create FUNCTION fn1() 
    RETURNS @t table(icode nvarchar(30), nid int) 
    AS
    BEGIN 
        declare @tb table(nid int identity(1,1),icode nvarchar(30)) 
        insert into @tb select icode from NT_Insurance_NetVTbl order by OneMonthPer desc 
        declare @nid int,@nid2 float,@count int 
        select @count=count(*) from NT_Insurance_NetVTbl

    insert into @t
    select t.icode, nid=ceiling(tb.nid*10.0/@count)
    from t join @tb tb on t.icode=tb.icode  return   
    END
    GOselect * from dbo.fn1() t