1

첨부 된 테이블은 앞의 각 테이블에있는 행 수를 나타 내기 위해 각 테이블 옆에 주석이있는 내 스키마를 배열하는 fiddle입니다. 그러나 나는 몇 가지 단계 곳이 수행Explain plan 15 분석 기능을 사용하는 쿼리에 필요한 Exabyte 공간 및 고유함

select distinct cat_name,cat_age, co_cat_owners_id,cat_weight,cs_is_alive,os_is_current, cos_is_current, 
     sum(cat_age) over(partition by co_cat_owners_id) running_total 
from 
    (
     select co.cat_owners_id co_cat_owners_id, 
       co.cat_id co_cat_id, 
       co.owner_id co_owner_id, 
       co.vet_id co_vet_id, 
       cos.is_current cos_is_current, 
       os.is_current os_is_current, 
       cs.is_alive cs_is_alive, 
       cat.name cat_name, 
       cat.age cat_age, 
       cat.weight cat_weight 
     from cat_owners co, 
       cat_owner_statuses cos, 
       cat_statuses cs, 
       cats cat, 
       owners o, 
       owner_statuses os 
     where o.owner_id = co.owner_id 
     and cat.cat_id = co.cat_id 
     and cos.last_visit >= sysdate - 4/24 
    ) 
where cs_is_alive = '1' 
and (cos_is_current = '1' OR os_is_current='1') 
group by cat_name,cat_age,cat_weight,cs_is_alive,os_is_current,co_cat_owners_id,cos_is_current; 

내 개발 환경에서 계획 단계의 측면에서, 바이올린 내부에 무엇에 매우 밀접하게 배치합니다 설명 : 쿼리는 바이올린이 차단되는 경우에, 그래서처럼 보인다 메모리 크기는 행 개수가 4000P (페타 바이트) 인 15E (엑사 바이트)입니다. 내 질문은 어디에 색인 생성/나쁜 SQL의 라인을 따라 내가 15 이하의 공간과 시간에 해결할 수 있어야 문제에 대한 엑사 바이트 솔루션을 생성 할 수 있었다. 복합 인덱스 생성 단계를 약간 조정하면 약간 다른 결과가 나타 났지만 Exabyte 공간 요구 사항에 의해 여전히 차단됩니다. 미래의 경우 사람에

참고

은 도움이 조인 올바른와 함께 다음과 같은 기능을 실행하고, 의견을 모두 읽지 않습니다 :

analyze table table_name_here compute statistics; 

답변

3

쿼리에 FROM 절에 6 개의 테이블이 있지만 두 개의 조인 조건 만 지정했습니다. OWNERS에는 1 천만 개의 행이 있고 CAT_OWNERS에는 1 억 2 천만 개의 행이 있으므로이 조인은 1 억 2 천만 개의 행을 생성합니다. 그런 다음 CATS에 1 백만 행이 포함되어 있으므로이 시점에서 1 억 2 천만 행이 있다고 가정합니다. 그러나 거기에서 더 이상 조인 조건이 없습니다. 따라서 귀하의 1 억 2 천만 행 중간 결과는 1 천 2 백만 행 × 6 천억 행을 생산하는 5 억 행의 CAT_OWNER_STATUSES 테이블과 결합됩니다. 데카르트는 1000 만 행의 테이블에 CAT_STATUSES 테이블을 합류하면 60 조 개의 행이 생겨 1,000 만 개의 행이되고 이제는 6 * 10^23 행까지됩니다. 그리고 나서 당신은 데카르트 조인을 OWNER_STATUSES으로 다시 합칩니다.이 행은 9 억 5 천만 행으로 5.4 * 10^31 행을 제공합니다. 합리적인 수의 결과를 원할 경우 카디 전 곱을 피하기 위해 추가 조인 조건을 지정해야합니다.

테이블을 함께 결합하는 잠재적으로 모순되는 여러 방법이 있기 때문에 불행히도 귀하의 바이올린에서 데이터 모델을 따라하기가 약간 어렵습니다. CAT_VETS은 고양이를 수의사에게 매핑하지만 예를 들어 CAT_OWNERS도 마찬가지입니다. 데이터 및 예상 결과가 없으면 테이블을 결합하는 방법을 추측하는 것이 매우 어렵습니다.내 생각 엔 당신이 뭔가를 원한다는 것입니다. this modified fiddle

select distinct cat_name,cat_age, co_cat_owners_id,cat_weight,cs_is_alive,os_is_current, cos_is_current, 
     sum(cat_age) over(partition by co_cat_owners_id) running_total 
from 
    (
     select co.cat_owners_id co_cat_owners_id, 
       co.cat_id co_cat_id, 
       co.owner_id co_owner_id, 
       co.vet_id co_vet_id, 
       cos.is_current cos_is_current, 
       os.is_current os_is_current, 
       cs.is_alive cs_is_alive, 
       cat.name cat_name, 
       cat.age cat_age, 
       cat.weight cat_weight 
     from cat_owners co, 
       cat_owner_statuses cos, 
       cat_statuses cs, 
       cats cat, 
       owners o, 
       owner_statuses os, 
       cat_vets cv, 
       owner_vets ov 
     where o.owner_id = co.owner_id 
     and cat.cat_id = co.cat_id 
     and cos.cat_owners_id = co.cat_owners_id 
     and cs.cat_vets_id = cv.cat_vets_id 
     and os.owner_vets_id = ov.owner_vets_id 
     and ov.owner_id = o.owner_id 
     and co.vet_id = ov.vet_id 
     and co.vet_id = cv.vet_id 
     and cos.last_visit >= sysdate - 4/24 
    ) 
where cs_is_alive = '1' 
and (cos_is_current = '1' OR os_is_current='1') 
group by cat_name,cat_age,cat_weight,cs_is_alive,os_is_current,co_cat_owners_id,cos_is_current; 
+0

물론, 그 계획은 그다지 두려워하지 않을 것입니다. 매번 전체 테이블 스캔을 먹어야하는 것처럼 보일 것입니다.이 경우에는 15 엑사 바이트의 임시 공간을 파티셔닝하는 것보다 효율적입니다. – Woot4Moo

+0

@ Woot4Moo - 전체 테이블을 스캔하고 있습니까? 피들에 대한 쿼리 계획은 테이블 스캔을 수행하지 않습니다. 물론 일부 테이블의 전체 테이블 스캔이 실제 시스템에서 더 효율적일 수 있습니다 ... –

+0

oops 테이블 스캔으로'인덱스 전체 스캔 '을 잘못 읽었습니다. – Woot4Moo

2

사용하지 않기 때문에 cat_statuses, cat_owner_statuses 및 owner_statuses의 행을 나머지 테이블과 결합하는 데 실패한 조인 구문. 이렇게하면 각 테이블과 조인 된 테이블간에 교차 조인이 발생합니다. 두 '상태'테이블에 몇 행이 있습니까?

각 테이블을 쉼표로 나열하는 대신 조인 한 다음 위치를 사용하여 필터링하십시오. 내가

 from owners o, 
      join cat_owners co on o.owner_id = co.owner_id 
      join cats cat on cat.cat_id = co.cat_id 
      join cat_owner_statuses cos on XXXXX 
      join cat_statuses cs on XXXXX, 
      join owner_statuses os on XXXXX 
    where cos.last_visit >= sysdate - 4/24 
0

당신은 당신의 테이블의 몇 가지에 대한 관계가없는 ... SQL은 를 (또한 크로스 조인 수 있습니다) 쉼표로 구분 된 테이블을 처리하는 방법을 잘 모르겠습니다 (예 : cat_statuses 등) 그래서 제품 조인은 많은 수의 행을 반환합니다. 아마도 피들 예제에서 cat_vets이라는 테이블을 통해 참여해야합니다.

최소한 외부 where 조건을 파생 테이블 쿼리로 이동해야합니다. 밖에서 갖는 것은 비효율적이다.

+0

외부에 어디에 두는 것을 제안 하시겠습니까? 문제는 최신 is_alive 상태가 필요하며 조건을 충족하는 첫 번째 상태는 아닙니다. – Woot4Moo