2012-11-09 5 views
2

I는 다음과 같습니다 SQL 쿼리를 가지고 :오라클 LIMIT 1000 열은 제한

SELECT * 
FROM (
    SELECT t.*, 
      ROW_NUMBER() OVER (ORDER BY ...) rnum 
    FROM (
     ... original SQL goes here ... 
    ) t 
) 
WHERE rnum BETWEEN 1 AND 10 

제 질문은 원래 쿼리가 다른 테이블에 많은 수의 조인을 통해 1000 개 이상의 열을 선택한다는 것입니다. 오라클은 테이블이나 뷰 당 1000 열의 내부 제한을 가지고 있으며, 결과 집합을 제한하기 위해 사용하는 래퍼 SQL은이 제한이 적용되는 임시 뷰를 생성하여 모든 작업을 실패하게 만듭니다.

페이지 뷰를 생성하지 않거나 1000 열 제한의 영향을받지 않는 다른 방법이 있습니까?

나는이 모든 방법을 이미 완전히 알고 있기 때문에 작업을 청크로 분해하고 1000 개 이상의 열을 선택하지 않는 것이 좋습니다.

+7

"* 1000 개 이상의 열 선택 *", 데이터 모델에 대한 이상한 점이있는 것 같습니다. –

+4

@a_horse_with_no_name : 이상한 점은 특정 도메인에 관련성이 높고 필요한 단일 항목에 대한 1000 개 이상의 개별 데이터가 있음을 의미합니다.하지만 모든 도메인 컬렉션에서 극히 드문 경우라면, 다시 맞습니다. 전혀 도움이되지는 않지만 정확합니다. – FtDRbwLXw6

+5

데이터베이스 디자인 30 년 동안 나는 1000 개 이상의 컬럼을 필요로하는 엔티티를 본 적이 없다. 모델이 최적화되어 증상을 해결하기보다는 문제의 근본 원인을 해결할 수 있다면 놀랄 일이 아닙니다. –

답변

2

당신이 기운을 1000+ 열이있는보기가 있으므로 조금만 속일 수 있습니다.

select * 
    from foo f, foo2 f2 
where (f.rowid, f2.rowid) in (select r, r2 
           from (select r, r2, rownum rn 
             from (select /*+ first_rows */ f.rowid r, f2.rowid r2 
               from foo f, foo2 f2 
               where f.c1 = f2.a1 
                and f.c2 = '1' 
               order by f.c1)) 
           where rn >= AAA 
            and rownum <= BBB) 


order by whatever; 

이제는 가장 안쪽 비트에 where 절을 넣습니다 (예 : f.c1 = '1'로 지정).

BBB = 페이지 크기. AAA = 시작 지점

+0

설명을 위해,이 예제에서'f.c1'은 키 필드로되어 있나? 그리고 결과 집합이 정렬되어야하는 열을 어디에 두어야하는지 '무엇에 의한 질의'입니까? 나는 그렇게 생각했다. 그러나 내가 얻는 결과는 내가 거기에 놓은 것에 의해 정렬되지 않는다. 오늘 날짜가 기록되어 있습니다. 제가 지정한 첫 번째 주문 열은 내림차순 수정 날짜 였지만, 2011 년부터 시작한 결과가 주문되었습니다. 내 생각에이 방법과 가장 관련있는 순서는 다음과 같습니다. '. – FtDRbwLXw6

+0

주 주문은 내부 sql'order by f.c1'에 있습니다. 원하는 모든 것을 넣으십시오 (외부 순서는 논리적으로 같은 순서 여야합니다) – DazzaL

+0

예 f.c1 = f2.a1은 조인 키입니다 (당신은 몇 가지있을 수 있습니다). 나는 당신의 예에서 많은 테이블이 있다고 말했듯이 거기에 두 개의 테이블을 놓았습니다. 그래서 당신이 원하는 모든 테이블을 놓으십시오. 그들 모두를 결합 시키십시오, 그러나 당신은 적합하다고 생각합니다. 그 내부 SQL에 모두. 첫 번째 행 힌트는 오라클에게 처음 몇 가지 결과에만 관심이 있다는 것을 알려주는 것입니다 (전체 스캔에서이를 피할 수 있습니다). – DazzaL

0

페이지 번호 매김이 문제가 되나요 아니면 처음 10 개의 행만 반환합니까?

SELECT foo "c0", 
     bar "c1", 
     baz "c2", 
     ... 
FROM some_table 
WHERE ... and 
     rownum <= 10 
+1

이것은 페이지 매기기를위한 것이므로 매번 처음 10 개가 아닌 임의의 오프셋에서 시작하여 한 번에 결과 페이지를 반환 할 수 있어야합니다. – FtDRbwLXw6

3

좋아, 이것은 당신이 계획 한 것보다 더 나쁜 수행합니다,하지만 내 요점은 매김이 방법을 시도 할 수 있다는 점이다 : 그것은 후자의 경우, 당신은 할 수

WITH CTE AS 
(
    ... original SQL goes here ... 
) 

SELECT A.* 
FROM CTE A 
INNER JOIN (SELECT YourKey, 
        ROW_NUMBER() OVER (ORDER BY ...) rnum 
      FROM CTE) B 
ON A.YourKey = B.YourKey 
WHERE rnum BETWEEN 1 AND 10; 
+0

나는 당신의 대답에 대해 지금 이해하고 있습니다. 이 방법을 시도하고 여전히 동일한 1000 열 제한 오류가 발생합니다. 이 쿼리는 조인 된 데이터를 하위 쿼리 (Oracle에서 임시보기를 만들려고합니까?)로 사용하므로 열 제한이 적용되는 것으로 가정합니다. – FtDRbwLXw6

+0

@ drrcknlsn 그렇다면 1000 열을 가진 테이블을 가지고 직접 시도해 볼 필요가 있습니다. – Lamak

+0

명확한 설명을 위해, 내 테이블에는 1000 개 이상의 열이 없습니다 (모두 훨씬 적습니다). 나는 여러 테이블에 가입하고 있으며 모든 테이블의 모든 컬럼의 합계가 1000을 넘는다. – FtDRbwLXw6