2014-01-14 2 views
0

특정 가격 유형을 사용하여 결과를 반환해야하는 검색 절차가 있습니다. 이 가격 유형은 검색 자 액세스 권한을 부여한 고객에 따라 계산 된 가격입니다. 이 가격을 계산하기 위해 UDF를 사용합니다. 따라서 제출 된 검색에 따라 다양한 가격이 다시 올 수 있습니다. 검색되는 가격 유형 외에도 FROM 및 TO 가격을 기준으로 결과를 필터링 한 후 영업 마진 범위를 필터링해야합니다.계산 된 필드의 큰 결과 필터링

이 단순화되어 있지만 기본적으로 검색은 다음과 같이 보일 것입니다 ...

SELECT Name, Model, f_GetPrices(modelID, @userID, priceType) 
FROM products 
WHERE f_GetPrices(modelID, @userID priceType) Between @from and @to 
    AND (RetailPrice-f_GetPrices(modelID, @userID, priceType)/Retail Price * 100) Between @fromMargin and @toMargin 

문제는 내가 레코드 당이 UDF 4 번 전화 했어이다.

이것은 단순화 된 버전으로 일반적으로 모든 결과를 임시 테이블에 삽입합니다. 그런 다음 @pageSize 및 @pageNumber를 사용하여 원하는 페이지를 당기고 두 번째 결과에서 총 반환 된 행을 반환합니다. 이를 통해 UI에서 페이징을 수행하고 총 레코드 수를 표시 할 수 있습니다.

계산 된 가격을 임시 테이블에 덤핑 한 다음 거기에서 가져 오는 SELECT에서 WHERE 절을 수행하는 것으로 간주했습니다. 그러나 이미 페이징을 위해이 작업을 수행하고 있으므로 계산 된 가격의 모든 레코드를 임시 테이블에 덤프해야하며 가격 범위에있는 레코드 만 가져온 다음 페이징 및 총 레코드의 마지막 시간을 가져옵니다. 결과의 두 임시 테이블.

나는 이것을 수행하는 가장 좋은 방법을 찾으려고 노력하고있다.

select에서 UDF를 4 번 호출하면 SQL 엔진이이를 4 회 실행합니까, 아니면 한 번만 계산하고 그 결과를 레코드 당 4 개의 모든 위치에서 사용합니까?

10,000 레코드를 선택하고 그 중 100 개만 가격 기준 (From, To, FromMargin, ToMargin)을 충족한다면 100k를 얻기 위해 그 10k 레코드를 유지하는 것은 낭비처럼 보입니다. 초기 선택에 가격 범위를 적용하십시오. 하지만 SQL은 WHERE 절을 적용하기 위해 모든 10k 레코드에 대한 계산을 수행해야한다고 생각했습니다. 가격표를 계산하고, 임시 테이블에 덤프 한 다음 다시 선택하기 때문에 가격대를 계산할 때 동일한 부하입니까?

select * 
from (SELECT Name, Model, f_GetPrices(modelID, @userID, priceType) as fgp 
     FROM products 
    ) p 
WHERE fgp Between @from and @to and 
     (RetailPrice-fgp)/RetailPrice * 100) Between @fromMargin and @toMargin; 

가 나는 또한 약간의 마지막 조건 논리를 수정, 그래서 차이가 RetailPrice로 나눈 :

답변

0

은 단순히 하위 쿼리를 사용합니다.

+0

을 내 단순화 된 버전이지만 이미 t 전체 결과 호출을 하위 쿼리로 호출하여 페이징을 위해 선택할 수 있습니다.그래서 한 단계 더 깊게 갈 것입니다. 너무 멀리 하위 쿼리를 작성하면 성능 문제가 발생하기 시작합니까? –

+0

@ IshmaelStruan. . . SQL Server는 하위 쿼리 최적화 작업을 훌륭하게 수행합니다. 나는 추가 수준에 대해 걱정하지 않을 것이다. 가독성을 위해 CTE (with 문)를 사용할 수 있습니다. 이것들은 서브 쿼리와 본질적으로 같습니다. –

0

여기서 성능을 최적화하려면 f_GetPrices()을 스칼라 함수 대신 인라인 테이블 반환 함수로 다시 작성하십시오. 스칼라 함수는 보통 RBAR입니다.

SELECT 
    Name, Model, Price 
    FROM products 
    CROSS APPLY tvf_GetPrices(modelID, @userID, priceType) f 
    WHERE Price Between @from and @to 
    AND (RetailPrice - Price)/Retail Price * 100 Between @fromMargin and @toMargin 

귀하의 함수 정의는 다음과 같이 보일 것입니다 :

http://sqlmag.com/sql-server/inline-scalar-functions

http://sqlblog.com/blogs/adam_machanic/archive/2006/08/04/scalar-functions-inlining-and-performance-an-entertaining-title-for-a-boring-post.aspx

귀하의 수정 된 쿼리는 다음과 같이 보일 것이다 그것은에 표시되지 것

CREATE FUNCTION [dbo].[tvf_GetPrices](
    @modelId int, 
    @userID int, 
    @priceType int 
) 
    RETURNS TABLE 
    RETURN (
    SELECT foo AS Price 
    FROM bar 
    WHERE @modelId 
    etc 
) 
+0

기사를 읽은 후 이것이 의미가 있습니다 (왜 이런 식으로 혼란 스러울지라도). 나는 이것을 지금 시험해 볼 것이다. INNER JOIN 대신이 예에서 CROSS APPLY를 사용하는 이유는 무엇입니까? 나는 CROSS APPLY의 적용에 다소 혼란 스럽습니까? –

+0

불행히도 이것은 SQL2k이며 CROSS APPLY가 작동한다고 생각하지 않습니다. 내부 조인을 사용하여 오류를 가져 오려고합니다. –

관련 문제