문제

수천 개의 행을 반환하고 완료하는 데 오랜 시간이 걸릴 수 있는 복잡한 저장 프로시저가 있습니다.

쿼리가 실행되어 데이터를 가져오기 전에 반환될 행 수를 알아낼 수 있는 방법이 있습니까?

이는 Visual Studio 2005, Winforms 애플리케이션 및 SQL Server 2005를 사용하는 경우입니다.

도움이 되었습니까?

해결책

문제에 대한 해결책은 저장된 절차를 다시 작성하여 결과 세트를 다음과 같은 숫자로 제한하도록하는 것입니다.

SELECT TOP 1000 * FROM tblWHATEVER

SQL Server에서

SELECT * FROM tblWHATEVER WHERE ROWNUM <= 1000

오라클에서. 또는 각 호출의 결과 세트가 허용되도록 페이징 솔루션을 구현하십시오.

다른 팁

저장된 절차를 완료하는 데 오랜 시간이 걸린다고 언급했습니다. 데이터베이스에서 행을 선택하거나 호출자에게 행을 반환하는 과정에서 대부분의 시간이 발생합니까?

후자 인 경우 실제 행 대신 수를 얻는 SP의 미러 버전을 만들 수 있습니다. 그것이 전자라면, 자격이있는 행을 찾는 행위이기 때문에 실제로 할 수있는 일은 많지 않습니다.

줄을 먼저 계산하기 위해 저장된 Proc를 만드십시오.

테이블에서 count (*)를 선택하십시오

이를 계산할 수있는 앱의 비즈니스 로직 측면이 없다면, no. 데이터베이스는 라인 행이 어떻게되는지 알아 내기 위해 모든 위치 및 가입 논리를 수행해야하며, 이는 대부분의 시간이 SP에서 소비하는 데 소비됩니다.

절차를 실행하지 않고 절차의 행을 얻을 수 없습니다.

동일한 매개 변수를 받아들이는 다른 절차를 만들 수 있으며, 그 목적은 다른 절차가 얼마나 많은 행을 반환 해야하는지 알려주는 것입니다. 그러나이 절차에 필요한 단계는 일반적으로 주요 절차의 단계와 매우 유사하므로 기본 절차를 실행하는 한 약이 오래 걸립니다.

행 카운트를 얻으려면 저장 프로 시저의 다른 버전을 작성해야합니다. 필터링되지 않은 테이블 결합, 주문 제거 등을 제거 할 수 있기 때문에 이것은 훨씬 빠를 것입니다.

select firstname, lastname, email, orderdate  from 
customer inner join productorder on customer.customerid=productorder.productorderid
where orderdate>@orderdate order by lastname, firstname;

계산 버전은 다음과 같습니다.

select count(*) from productorder where orderdate>@orderdate;

일반적으로 아닙니다.

저장된 절차의 작동에 대한 지식을 통해 추정 또는 정확한 수를 얻을 수 있습니다 (예 : 쿼리의 "코어"또는 "기본"테이블이 신속하게 계산 될 수 있지만 복잡한 조인 및/또는 요약을하는 시간을 위로 향하게합니다).

그러나 카운팅 SP를 먼저 호출 한 다음 데이터 SP를 호출해야합니다. 그렇지 않으면 여러 결과 세트 SP를 사용하여 볼 수 있습니다.

실제 데이터를 얻는 데 행 카운트를 얻는 데 시간이 오래 걸릴 수 있으므로 대부분의 경우 카운트를 수행하는 것을 고문하지 않습니다.

몇 가지 가능성 :

1) SQL Server는 어떤 식 으로든 쿼리 최적화기 결과를 노출합니까? 즉, 쿼리를 구문 분석 한 다음 추정 RowCount의? (나는 SQL Server를 모른다).

2) 아마도 사용자가 자신의 평가를 수행 할 수있는 기준에 따라 자신의 추정을 수행 할 수 있습니다. 예를 들어, 사용자가 고객 성 필드에서 쿼리 주문에 'S%'를 입력하면 고객 기록의 7% (예 : 쿼리)와 일치하는 것을 결정할 수 있습니다. 5월 주문 기록의 약 7%를 반환합니다.

Tony Andrews가 답변에서 말한 내용을 따르면 다음을 사용하여 쿼리 호출에 대한 예상 쿼리 계획을 얻을 수 있습니다.

SET showplan_text OFF
GO
SET showplan_all on
GO
--Replace with call you your stored procedure
select * from MyTable
GO 
SET showplan_all ofF
GO

그러면 쿼리의 예상 행 수를 얻을 수 있는 하나 이상의 테이블이 반환됩니다.

반환되는 결과 집합에 대한 논리적(의미 있는) 기본 키가 무엇인지 확인하려면 반환된 데이터 집합을 분석해야 합니다.일반적으로 이는 전체 절차보다 훨씬 빠릅니다. 서버는 각 테이블의 각 행에 있는 모든 열의 데이터에서 결과 집합을 구성하지 않고 단순히 행 수를 계산하기 때문입니다.일반적으로 이를 수행하기 위해 디스크에서 실제 테이블 행을 읽을 필요조차 없으며 단순히 인덱스 노드 수를 계산해야 할 수도 있습니다.

그런 다음 해당 키 열을 생성하는 데 필요한 테이블(기본 SQL 쿼리에 있는 테이블의 하위 집합이길 바랍니다)만 포함하는 다른 SQL 문과 동일한 필터링 조건자 값을 가진 동일한 where 절을 작성합니다.

그런 다음 Stored Proc에 @CountsOnly라는 또 다른 Optional 매개변수를 추가하고 기본값은 false(0)입니다.

Alter Procedure <storedProcName>
@param1 Type, 
-- Other current params
@CountsOnly TinyInt = 0
As
Set NoCount On

   If @CountsOnly = 1
       Select Count(*) 
       From TableA A 
          Join TableB B On   etc. etc...
       Where < here put all Filtering predicates >

   Else
      <Here put old SQL That returns complete resultset with all data>

  Return 0

그런 다음 @CountsOnly를 1로 설정하여 동일한 저장 프로시저를 호출하여 레코드 수를 가져올 수 있습니다.proc을 호출하는 이전 코드는 매개변수 값이 포함되지 않은 경우 기본값이 false(0)로 설정되므로 예전처럼 계속 작동합니다.

최소한 기술적으로 결과 세트를 임시 테이블에 넣는 절차를 실행하는 것이 가능합니다. 그런 다음 데이터를 서버에서 애플리케이션으로 이동하기 전에 행 수를 찾을 수 있으며 결과 세트를 두 번 만들어야합니다.

그러나 결과 세트를 만들지 않으면 문제가 될 가치가있는 것은 매우 오랜 시간이 걸리지 않으며,이 경우 온도 테이블이 문제가 될 정도로 충분히 클 수 있습니다. 네트워크를 통해 큰 테이블을 움직일 때가 거의 확실하게 생성하는 데 필요한 것들이 될 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top