2009-04-16 1 views
1

SQL Server 08에서이 끔찍한 비효율적 인 UDF를 최적화 할 수있는 방법이 있습니까? UDF를 처음 접했을 때 특히 최적화를 위해 새로보고 있습니다.SQL Server 2008에서이 끔찍한 비효율적 인 사용자 정의 함수를 최적화하는 방법 08

업데이트 : 쿼리의 각 행과 각 열에서이 작업을 수행하려는 경우이 기능으로 열을 보내야합니까? 이 문제를 해결할 더 좋은 방법이 있습니까?

는 감사

** @value (플로트)과 @fieldname (VARCHAR (40))입니다 입력 매개 변수 **

BEGIN 
    DECLARE @UT integer, @FRM integer, @TO integer, @FACTOR float 

    select @UT = [UF_UT_ID] FROM dbo.UNIT_FIELDS where [UF_FIELD][email protected] 
    select @FRM = [UT_UN_ID_INTERNAL_UNITS] from dbo.UNIT_TYPES where [UT_ID][email protected] 
    select @TO = [UT_UN_ID_DISPLAY_UNITS] from dbo.UNIT_TYPES where [UT_ID][email protected] 
    select @FACTOR = [UC_SLOPE] from dbo.UNIT_CONVERSIONS where [UC_UN_ID_UNIT_FROM][email protected] and [UC_UN_ID_UNIT_TO][email protected] 

    -- Return the result of the function dbo. 
    RETURN @FACTOR*@value 
END 
+0

방법이 UDF가 비효율적임을 알 수 있습니까? SQL 프로파일 러에서 뭔가를 보았습니까? – MedicineMan

답변

1

1 단계는 각각 개별적으로 선택하고 위치를 확인할 실행하는 것입니다 병목 현상이 있습니다.

3

PK/FK 관계를 기반으로 세 개의 테이블을 조인 할 수 있다면 쿼리를 단일 선택으로 가져올 수 있습니다. 그렇지 않은 경우에만 즉시 명백한 최적화는 하나의 select 문에서 @FRM 및 @TO을 할당하는 것입니다 :

select @FRM = [UT_UN_ID_INTERNAL_UNITS], @TO = [UT_UN_ID_DISPLAY_UNITS] from dbo.UNIT_TYPES where [UT_ID][email protected] 
2

인라인 테이블 함수에 대한 고전적인 후보 ...

뭔가 같은 :

ALTER FUNCTION fnName(@value float, @fieldName VARCHAR(100)) 
RETURNS TABLE 
AS 
RETURN 
(
    SELECT @value * 
     (SELECT conv.[UC_SLOPE] from dbo.UNIT_CONVERSIONS conv 
     JOIN dbo.UNIT_TYPES UT_UN_ID_INTERNAL_UNITS ON where [UC_UN_ID_UNIT_FROM]=UT_UN_ID_INTERNAL_UNITS.[UT_ID] 
     JOIN dbo.UNIT_TYPES UT_UN_ID_DISPLAY_UNITS ON where [UC_UN_ID_UNIT_TO]=UT_UN_ID_DISPLAY_UNITS.[UT_ID] 
     JOIN dbo.UNIT_FIELDS fields ON (UT_UN_ID_INTERNAL_UNITS.[UT_ID] = fields.[UF_UT_ID]) AND (UT_UN_ID_DISPLAY_UNITS.[UT_ID] = fields.[UF_UT_ID]) 
     WHERE ([UF_FIELD][email protected]) 
     ) 
) 
0

하나 개의 작은 것은 당신이 할 수 있습니다

select @FRM = [UT_UN_ID_INTERNAL_UNITS] from dbo.UNIT_TYPES where [UT_ID][email protected] 
select @TO = [UT_UN_ID_DISPLAY_UNITS] from dbo.UNIT_TYPES where [UT_ID][email protected] 

내가 읽은 경우 올바르게는 것

select @TO = [UT_UN_ID_DISPLAY_UNITS], 
     @FRM = [UT_UN_ID_INTERNAL_UNITS] 

from dbo.UNIT_TYPES where [UT_ID][email protected] 

동일한 레코드에서 선택을 두 번 실행하는 이유는 무엇입니까?

0

이것은 JOIN 년대를 사용하여 다시 작성해야합니다 :

SELECT c.UC_SLOPE * @value 
FROM unit_fields f 
JOIN unit_types t 
ON  t.UT_ID = f.UF_UT_ID 
JOIN unit_conversions c 
ON  c.UC_UN_ID_UNIT_FROM = t.UT_UN_ID_INTERNAL_UNITS 
     AND c.UC_UN_ID_UNIT_TO = t.UT_UN_ID_DISPLAY_UNITS 
WHERE f.UF_FIELD = @field_name 
0
BEGIN 
    DECLARE @FACTOR float 

    select @factor = UC.UC_SLOPE 
     from dbo.UNIT_CONVERSIONS UC, 
      dbo.UNIT_TYPES  UT, 
      dbo.UNIT_FIELDS  UF 
     where [email protected] 
     and UT.UT_ID = UF.UF_UT_ID 
     and UC.UC_UN_ID_UNIT_FROM = UT.UT_UN_ID_INTERNAL_UNITS 
     and UC.UC_UN_ID_UNIT_TO = UT.UT_UN_ID_DISPLAY_UNITS 


    -- Return the result of the function dbo. 
    RETURN @FACTOR*@value 
END 
0

당신은 모두 하나 개의 쿼리로이 시도 할 수 있습니다 :

--Decalre Factor var 
DECLARE @FACTOR float 

SELECT @FACTOR = [UC_SLOPE] 
FROM dbo.UNIT_CONVERSIONS uc 
--Join the Unit Types table to Unit Conversions on the old From & To types 
INNER JOIN dbo.UNIT_TYPES ut ON 
    ut.[UT_UN_ID_DISPLAY_UNITS] = uc.[UC_UN_ID_UNIT_TO] 
    AND ut.[UT_UN_ID_INTERNAL_UNITS] = uc.[UC_UN_ID_UNIT_FROM] 
--Join the Unit Files on the Unit Types 
INNER JOIN dbo.UNIT_FIELDS uf ON 
    uf.[UF_UT_ID] = ut.[UT_ID] 
WHERE uf.[UF_FIELD][email protected] 

-- Return the result of the function dbo. 
RETURN @FACTOR*@value 
관련 문제