문제

SQL Server 2005를 사용하여 PAGED 검색 저장 프로 시저를 작성했습니다. 여러 매개 변수가 필요하며 검색 기준은 적당히 복잡합니다.

프론트 엔드 아키텍처로 인해 돌아올 결과 수를 반환 할 수 있어야합니다. 없이 실제로 결과를 반환합니다. 그런 다음 프론트 엔드는 저장 절차를 두 번째로 호출하여 실제 결과를 얻습니다.

한편으로는 두 개의 저장된 절차를 작성할 수 있으며, 하나는 카운트를 처리하고 실제 데이터를 처리하기 위해 하나는 검색 로직을 최소한 두 개의 다른 장소로 유지해야합니다. 또는 저장된 절차를 작성하여 약간의 매개 변수를 가져 와서 데이터를 반환하거나 카운트만으로도 작성할 수 있습니다. 데이터로 임시 테이블을 채우고 카운트가 있다면 그로부터 카운트 만하면 선택을 수행 할 수 있습니다. 여기서 문제는 카운트 프로세스를 최적화 할 수 있으므로 더 많은 오버 헤드가 될 수 있다는 것입니다 (불필요한 열 등을 얻어야합니다). 또한 저장된 프로 시저에서 이러한 종류의 논리를 사용하면 두 용도 사이를왔다 갔다 할 때 쿼리 계획이 잘못 될 수 있습니다.

시스템의 데이터 양은 너무 높지 않습니다 (더 큰 테이블에 대해서도 2 백만 행만). 동시 사용자가 많이있을 수 있습니다.

이 접근법에 대한 사람들의 생각은 무엇입니까? 내가 생각하지 않은 방식 으로이 문제를 해결 한 사람이 있습니까?

그들 할 수 없습니다 결과를 가져 와서 동시에 한 번의 통화에서 계산하십시오.

감사!

도움이 되었습니까?

해결책

개인적으로 두 쿼리 접근 방식을 사용합니다. 예, 검색 논리를 두 곳에서 유지해야하지만 성능 최적화 이점과 코드의 전반적인 청소가 결국 지불된다는 것을 알았습니다.

단일 절차로 전달 된 깃발을 사용하는 것은 잠재적 인 해결책이지만, 특히 복잡한 검색 논리를 위해 유지하기가 매우 어렵다는 것을 알게됩니다.

임시 테이블 등을 사용하는 경로는 필요한 것보다 더 많은 오버 헤드를 추가합니다.

따라서 왜 두 쿼리 방법으로 착륙 한 이유. 온라인에서 찾은 모든 것은이 접근법도 권장합니다.

다른 팁

이것은 정상적인 문제가 아니며 일반적으로 페이지를 얻는 동시에 총 카운트를 원합니다.

즉, 두 가지 절차를 사용하십시오. 그 이유는 당신이 서로 표면적으로 만 닮은 두 가지 매우 다른 행동이 있기 때문입니다.

나는 당신이 이것을 고려했다고 확신합니다 : 데이터가 카운트를 변경하고 있으며 그 이후의 실제 페이징이 다를 수 있다면 (행이 추가 / 제거 된 경우)

일치하는 행의 PK를 반환하는 사용자 정의 함수를 가질 수 있으며, 비교적 쉽게

SELECT COUNT(*) FROM dbo.MyQueryFunction(@Param1, @Param2)

카운트를 얻기 위해

SELECT Col1, Col2, ...
FROM dbo.MyQueryFunction(@Param1, @Param2) AS FN
     JOIN dbo.MyTable AS T
         ON T.ID = FN.ID
     ... more JOINs ...

데이터를 얻으려면.

이것이 후속 페이징에 대해 row_number가 얼마나 잘 있는지 모르지만, MyQueryFunction에 포함 된 실제 "쿼리 로직"을 유지할 것입니다. 스프로와 스프로에서 검색 할 열에 대한 모든 조인이 여전히 결합 될 것입니다. 함수.

특정 문제에 도움이되지 않지만 SQL 2005는 페이징 검사에 편리한 Row_number 기능을 소개합니다.

row_number 예제

임시 테이블보다 훨씬 쉽습니다.

이 스레드가 다른 것을 연구하는 것을 발견했으며 결과 세트와 레코드 수를 하나의 쿼리로 반환 할 수 있다고 언급했습니다. 값을 전달하려면 'Out'매개 변수 만 있으면됩니다. 아래는 Oracle 예제의 복사/페이스트이지만 SQL Server 에서이 기술이 매우 유사합니다 (SQL Server ATM에 액세스 할 수 없습니다).

SQL Server의 가장 큰 것은 Row_number () 대 Rownum을 사용해야 할 수도 있다는 것입니다.

procedure get_sample_results (
    startrow in number default 1,
    numberofrows in number default 10,
    whereclause in varchar2,
    matchingrows out number,
    rc  out sys_refcursor
)
is
    stmnt varchar2(5000);
    endrow number;
begin

    stmnt := stmnt || 'select * from table t where 1=1';
    if whereclause is not null then
        stmnt := stmnt || ' and ' || whereclause;
    end if;

    execute immediate 'select count(*) from (' || stmnt || ')' into matchingrows;

    stmnt := 'select * from (' || stmnt || ') where rownum between :1 and :2';        

    -- must subtract one to compenstate for the inclusive between clause
    endrow := startrow + numberofrows - 1;
    open rc for stmnt using startrow, endrow;

end get_sample_results;

나는 이것 (이미 표시된)을 알고 있지만 레코드 세트 (일명 결과)를 반환하고 출력 (또는 다중 출력) 값을 가질 수 있습니다. 즉, 데이터베이스로의 왕복이 하나만 필요하다는 것을 의미합니다.

이것은 내가 큰 소리로 생각하고있는 것입니다 (그리고 내 침대 시간을 지나서 waaay입니다 ...)

CREATE PROCEDURE WhatEver
(
   @SomeParam1 NVARCHAR(200),
   ....
   @SomeParam_X INT,
   @NumberOfResults INTEGER OUTPUT
)
BEGIN
    SET NOCOUNT ON

    -- Do your search stuff.
    -- ....
    SELECT Whatever
    FROM WhatWhat
    ...

    -- Ok, the results/recordset has been sent prepared.
    -- Now the rowcount
    SET @NumberOfResults = @@ROWCOUNT
END

HTH.

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