2010-04-15 10 views
1

두 개의 엔티티 A와 B가 있습니다.이 관계는 다수 관계와 관련이 있습니다. 엔티티 A는 최대 100 개의 B 엔티티와 관련 될 수 있습니다. 엔티티 B는 최대 10000 개의 A 엔티티와 관련 될 수 있습니다. 예를 들어 30 개의 A 엔티티를 선택하는 빠른 방법이 필요합니다. B 엔티티는 지정된 B 엔티티와 관계가 있으며 필터링 및 다른 속성으로 정렬됩니다.인덱싱 SET 필드

여기 내가 이상적인 솔루션을 보는 방법 : B 엔티티와의 관계를 포함하여 A 엔티티에 대해 알고있는 모든 정보를 단일 행 (SET 필드가있는 특수 테이블)에 넣은 다음 필요한 모든 인덱스를 추가합니다. 문제는 SET 필드로 쿼리하는 동안 인덱스를 사용할 수 없다는 것입니다. 어떻게해야합니까? 그게 도움이된다면, 데이터베이스를 다른 것으로 대체 할 수 있습니다.

업데이트 : 죄송합니다. 하나의 중요한 세부 사항을 언급하는 것을 잊어 버린 것처럼 보입니다. id = 1 인 B 항목과 id = 2 인 B 항목과의 관계가있는 항목을 찾아야합니다. , a.id = ab.a_id WHERE ab.b_id IN (1 일에 INNER 가입 AB의 탄소 나노 튜브로, 계산

SELECT a.id (*) : 사용하여 조인을한다면 나는 비슷한있을 것이다 NULL을 갖는 탄소 나노 튜브 BY a.id ORDER BY 2) GROUP = 나에게 아주 나쁜 perfomance를 제공 ​​2

답변

1

당신은이하지 않는 이유 :

SELECT * 
FROM a 
WHERE a.id IN 
     (
     SELECT ab.a 
     FROM b 
     JOIN ab 
     ON  ab.b = b.id 
     WHERE b.id IN (1, 2, 3, 4) 
     ) 

을하고 PRIMARY KEY을 만들에?

업데이트 :

사용이 :

SELECT * 
FROM a 
WHERE (
     SELECT COUNT(*) 
     FROM ab 
     WHERE ab.a = a.id 
       AND ab.b IN (1, 2, 3, 4) 
     ) = 4 
ORDER BY 
     ... 
LIMIT 30 

나이 :

SELECT a.* 
FROM (
     SELECT a 
     FROM ab 
     WHERE ab.b IN (1, 2, 3, 4) 
     GROUP BY 
       a 
     HAVING COUNT(*) = 4 
     ) q 
JOIN a 
ON  a.id = q.id 
ORDER BY 
     ... 
LIMIT 30 

이 빠르게 작업 할 수 있습니다 (순서대로) ab (b, a)PRIMARY KEY을해야합니다 .

더 효율적인 쿼리는 데이터 배포에 따라 다릅니다.

+0

죄송합니다. 하나의 중요한 세부 사항을 언급하는 것을 잊어 버린 것처럼 보입니다. id = 1 인 B 항목과 id = 2 인 B 항목과의 관계가있는 항목을 찾아야합니다. 그래서 조인을 사용한다면 다음과 비슷한 것을 보게 될 것입니다 : SELECT a.id, count (*)를 cnt로 시작합니다. 내부 조인에서 ab.id = ab.a_id 어디에서 ab.b_id IN (1,2) GROUP BY a.id cnt = 2 인 ORDER BY NULL 이것은 나에게 매우 나쁜 성능을 제공합니다. – Dienow

+0

이것은 여전히 ​​성능이 좋지 않습니다. 일부 입력 값의 경우 쿼리를 수행하는 데 최대 1 초가 걸리고 내 경우에는 받아 들일 수 없습니다. 문제는 b의 엔터티가 a의 수천 개의 엔터티와 연결될 수 있다는 것입니다. 이것이 하위 쿼리가 너무 많은 행을 처리해야하는 이유이며, 필요한 모든 데이터가 인덱스 (USING INDEX)에서 가져온 경우에도 상당히 나쁜 성능을 제공합니다. – Dienow

+0

@Dienow :'EXPLAIN SELECT ... '의 출력을'SHOW CREATE TABLE a' 및'SHOW CREATE TABLE b' 출력과 함께 게시 할 수 있습니까? – Quassnoi