2012-05-01 2 views
1

전체 뭉치를 반환하는 저장 프로 시저를 실행하고 싶습니다. 그 중 하나는 쉼표로 구분 된 결과 문자열입니다.SQL 쿼리 콤마로 구분 된 문자열로 결과를 반환합니다. (최적화 됨)

은 내가 COALESCE에 대해 읽고 다음과 같이 그것을 수행하는 함수를 만들었습니다 :이 함수를 호출 예상대로 작동 SELECT

DECLARE @ListOfStuff NVARCHAR(4000) 

SELECT @ListOfStuff = COALESCE(@ListOfStuff + ', ', '') + Z.SingleStuff 
FROM X 
INNER JOIN Y ON X.SomeId = Y.Id 
INNER JOIN Z ON Y.SomeId = Z.id 
WHERE --Some condition 

RETURN ISNULL(@ListOfStuff, '') 

그리고 내 주에 있습니다. 그러나 절차가 실행되는 데 실제로 시간이 오래 걸리고 종종 시간이 초과됩니다. 내가 궁금해하는 점은 누군가 최적화 방법을 알고 있는지 여부입니다. 나는이 함수를 없애고이 논리를 프로 시저에 통합하면 훨씬 빠르게 실행될 수 있다고 믿지만이 방법으로 COALESCE를 사용하는 sub select를 가질 방법을 찾지 못했습니다.

이 아이디어를 어떻게 최적화 할 수 있습니까?

+0

을 사용하고있는 RDBMS 및 버전 : 다음과 같이 당신이 찾고있는 솔루션에

내 추측은? – JNK

답변

0

COALESCE 정말 여기에 일을하지 않는 사전에 많은 감사 -의 @ListOfStuff 변수를 사용하여 수행되는 쉼표로

값의 연결을, (그것은 단지 널 (null)을 정렬 http://msdn.microsoft.com/en-us/library/ms190349.aspx 참조) 그리고 그것을 수행하는 좋은 (유일한?) 방법 인 것처럼 보입니다. 즉, 함수를 없애면 저장 프로 시저에서 여전히 필요합니다. 기능을 가지고 있으면 스스로보고있는 성능이 저하되지 않아야합니다.

따라서 조인 열 (id, SomeId)의 색인을 생성하는 것 이외의 다른 방법을 최적화 할 수 있는지 잘 모르겠습니다.

2

@ListOfStuff를 ''로 선언 한 다음 문자열 연결 및 최종 반환 값을 약간 다르게 처리하여 COALESCE를 모두 제거 할 수 있습니다. 그대로 서서 모든 행에서 평가하고 있습니다.

DECLARE @ListOfStuff NVARCHAR(4000) = '' 

SELECT @ListOfStuff = @ListOfStuff + Z.SingleStuff + ',' 
FROM X 
INNER JOIN Y ON X.SomeId = Y.Id 
INNER JOIN Z ON Y.SomeId = Z.id 
WHERE --Some condition 

IF LEN(@ListOfStuff) > 0 
BEGIN 
    SELECT @ListOfStuff = LEFT(@ListOfStuff, LEN(@ListOfStuff) - 1) 
END 
RETURN @ListOfStuff 

가능한 최적화 인덱스가 조인에 사용 된 모든 열을가 보장하기 위해, 그리고 당신이 NVARCHAR보다는 VARCHAR를 사용할 수 있는지 (물론, 내용과 z.SingleStuff의 데이터 유형에 따라) 것 그게 조금 도움이 될거야. 그러나 나는 그것을 호출하는 스토어드 프로 시저를 크게 재 작성하지 않으면 무엇을 할 수 있는지 잘 모르겠습니다.

SELECT의 모든 행에 대해이 함수를 호출하는 경우 테이블 값 함수 또는 CROSS APPLY (사용 방법 및 RDBMS에 따라 다름)에 약간의 행운이있을 수 있습니다.

0

SP를 보지 못하면 실제 해결책을 제안 할 수 없지만 SQL Server를 사용하는 경우에는 FOR XML PATH 접근 방식을 사용할 수 있습니다.이 방법은 여러 가지 질문에 특색이 있습니다. 나는 최근에이 접근법의 논리를 무너 뜨리는 질문에 대답했다. here. 필자는 함수가 SQL의 기본 집합 기반 접근 방식에서 벗어나 기능 접근 방식을 선호합니다.

KM은 더 나은 솔루션 here에 대한 링크를 사용하여 내 접근법의 결함을 지적했지만, 동일한 로직이 여전히 적용되지만 KM은 예약 된 문자가 병합 된 텍스트에 나타나는 문제를 피했습니다. 당신이

SELECT X.SomeColumn, 
     Y.SomeColumn, 
     STUFF((SELECT ', ' + Z.SingleStuff 
       FROM Z 
       WHERE Z.ID = Y.SomeID 
       FOR XML PATH(''), TYPE 
      ).Value('.', 'VARCHAR(MAX)'), 1, 2, '') [ListOfStuff] 
FROM X 
     INNER JOIN Y 
      ON X.SomeId = Y.Id 
WHERE --Some condition