2014-05-27 3 views
2

SQL Fiddle에 대한 다음 스키마를 고려하십시오. 보시다시피 다형성 연관을 모델링하기위한 수퍼 테이블 스키마를 따릅니다. 실제 구현에서는 foo, bar 및 baz 테이블이 서로 매우 다르다는 점을 기억하십시오.여러 가능한 테이블에 가입

, 내 첫 번째 아이디어는 여러 LEFT OUTER 조인을 사용하는 것이었다 내가 직면하고있어 문제는 내가 해당 대상에 해당 소유자에 대한 모든 활동을 검색 할 필요가있다

: 는이 쿼리를

SELECT * 
FROM activities 
LEFT OUTER JOIN foo ON activities.target_id = foo.activitable_id 
LEFT OUTER JOIN bar ON activities.target_id = bar.activitable_id 
LEFT OUTER JOIN baz ON activities.target_id = baz.activitable_id 
WHERE activities.owner_id = 1 

괜찮음 나는 각 테이블마다 3 개의 테이블을 하나의 행으로 결합한다고 생각하지만 스키마가 각 테이블의 10k 행과 8 개의 조인으로 커지면 성능에 큰 영향을 미칩니다.

제 질문은 더 빠른 쿼리로 원하는 것을 얻을 수있는 방법이 있습니까?

+5

외래 키에 대한 인덱스 추가 – Donal

+1

쿼리가 괜찮습니까? 나는 foo/bar/baz 레코드를 곱하는 것 같아요. 당신은 노동 조합을 사용할 수 있다고 생각합니다. – Arvo

+3

전송할 데이터가 적기 때문에 *를 선택하는 대신 필요한 필드 만 선택하면 항상 빠릅니다. –

답변

1

성능에 큰 영향을 줄 필요가 없습니다. 테이블 당 하나의 인덱스 (기본 키에있는 인덱스)로만 데이터 구조를 정의했습니다. 즉, 조인의 효율성이 떨어집니다.

구조를 고려해 볼 때 어떤 테이블에도 activitable_id이 중복되는 것을 원하지 않습니다. 이 같은 각 테이블이 정의되어야한다 뭔가 : 그것은 모두 고유성을 적용하고 성능을 개선해야하는 열에 고유 인덱스를 생성하기 때문에

CREATE TABLE foo (
    id serial primary key, 
    name varchar(20), 
    activitable_id int UNIQUE, 
    FOREIGN KEY (activitable_id) REFERENCES activitables(id) 
); 

activitable_id 선언은 고유 한 주소를 모두 이러한 문제가 될 수 있습니다.

+0

당신은 절대적으로 옳습니다. @Donal은 전에 언급 한 내용에 대해 여러분은 대답이 가장 완벽하다고 지적했습니다. 나는 아직도 색인을 추가하지 못한 것을 알고있다. 고맙습니다! –

1

당신은 쿼리에서 사용되는 열에 인덱스를 추가 할 수 있습니다 : 당신은 모든 테이블에 적용 할 수있는 필터 조건이있는 경우

activities.target_id 
foo.activitable_id 
bar.activitable_id  
baz.activitable_id 

, 그 성능도 좋을 것 때문에 당신은 더 작은 데이터의 부분 집합에서 작동 할 것입니다. 예 :

SELECT * 
FROM activities 
LEFT OUTER JOIN (SELECT * FROM foo WHERE name like 'A%') foo ON activities.target_id = foo.activitable_id --Filter applied to limit rows using the name 
LEFT OUTER JOIN (SELECT * FROM bar WHERE id < 10) bar ON activities.target_id = bar.activitable_id --Filter applied to limit rows using id 
LEFT OUTER JOIN (SELECT * FROM baz WHERE activitable_id = 1) baz ON activities.target_id = baz.activitable_id --Filter applied to limit rows using activitable_id 
WHERE activities.owner_id = 1; 
+0

서식을 죄송합니다. 내 브라우저인지는 모르겠지만 서식과 관련된 문제가있는 것으로 보입니다. –

+0

형식이 좋습니다. 팁은 성능 향상에도 도움이됩니다. 감사합니다. –

+0

당신을 환영합니다! :-) –