2013-07-09 2 views
1

내가 가진 친구 누구의 테이블을 가지고, 간단하게 다음과 같은있다 : 고유하지 않은 인덱스테이블에 친구 쌍이있는 경우, 사용자의 친구 목록을 가져 오는보기를 만드는 방법은 무엇입니까?

user_id1 | user_id2 | <some other data>

: index_on_user1index_on_user2

은 모두 열 데이터의 동일한 유형을 포함, 항상 우정 양방향으로 간다.

1 | 2

= 사용자 12 사용자와 친구이며, 사용자는 사용자 21와 친구이다.

내가 원하는 것은 내가 제공 한 user_id가 무엇이든 관계없이 항상 친구 목록을 제공하는 쿼리를 얻는 것입니다.

지금까지 최대

, 나는

SELECT if(`user_id1` = $user_id, `user_id2`, `user_id1`) as friend 
FROM `Friends` 
WHERE `user_id1` = $user_id OR `user_id2` = $user_id 

을 사용하고하지만 난 하위 쿼리와이 정보를 얻을, 그리고 등이 쿼리를 포함하는 뷰를하고 싶습니다 더 쿼리를 가지고 하위 쿼리. 그래서 이것을 추상화하는 방법을 찾고 있었는데, if 성명서를 사용하지 않고도 친구의 ID를 항상 얻을 수있는 간단한 선택이 필요했습니다.

CREATE OR REPLACE VIEW get_friend AS 
SELECT 
    `user_id1` as subject, 
    `user_id2` as friend, 
    FROM `Friends` 
    USE INDEX (`index_on_user1`) 
UNION 
SELECT 
    `user_id2` as subject, 
    `user_id1` as friend, 
    FROM `Friends` 
    USE INDEX (`index_on_user2`) 

이 결과를 얻기 위해 간단한 SELECT friend FROM get_friend WHERE subject = $user_id를 사용하여, 그것은 작동합니다

나는 노동 조합과 함께이 아이디어를 가지고있다.

그러나 explain select...에는 색인을 사용하지 않으며 힌트가 포함되어 있지 않습니다.

어떻게 이러한 인덱스를 사용할 수 있습니까? 심지어 가능할까요? 다른 해결책이 있습니까?

+0

저장 프로 시저가 ID를 쿼리로 대체 할 수 있으므로 저장 프로 시저가 더 잘 작동 할 수 있습니다. – Barmar

답변

1

인덱스를 사용하려면 UNION 문의 개별 쿼리에 WHERE 절이 있어야합니다. 기본적으로 뷰에 대한 쿼리는이

SELECT subject, friend FROM 
(SELECT 
    `user_id1` as subject, 
    `user_id2` as friend, 
    FROM `Friends` 
    USE INDEX (`index_on_user1`) 
UNION 
SELECT 
    `user_id2` as subject, 
    `user_id1` as friend, 
    FROM `Friends` 
    USE INDEX (`index_on_user2`) 
) WHERE friend = <some number> 

는이 조항이 채워 적절한으로 UNION에 대해 쿼리를 EXPLAIN 실행 시도하고있다 그리고 당신은 인덱스가 사용되는 것을 볼 수 있습니다.

+0

그래서 당신은보기를 사용하지 않는 것을 의미합니다. 그러나 노동 조합은 직접 작동해야합니다. – enrey

+0

@enrey 예, 정확하게 – dethtron5000

1

한보기에서 다른 색인을 사용할 수 없습니다. 원하는 성능을 얻으려면 필요한 곳에서 원시 SQL (예 : 공용)을 코딩해야합니다.

더 나은 해결책은 관계의 양방향을 저장하는 것입니다. 그것은 일부 비정규 화 된 데이터입니다. 이렇게하면 쿼리가 간단 해지고 잘 수행됩니다.

"다른 데이터"를 저장하지 않으려면 ID만으로 새 테이블을 만들 수 있습니다. 트리거를 사용하여 기본 테이블과 정렬 된 상태로 유지하십시오.

관련 문제