문제

나는 다음과 같은 테이블을 가지고 있습니다 :

Matches -> match_id, team_a_id , team_b_id, score

이 테이블에는 두 팀(A팀과 B팀) 간의 경기가 기록됩니다.그러나 A팀이 호스트로 플레이할 때도 있고, B팀이 호스트로 플레이할 때도 있습니다.그래서 A팀과 B팀의 전적 경기를 찾아보려고 했을 때.내가 현재 하고 있는 일은

select * from matches where (team_a_id = 1 and team_b_id = 2) or (team_a_id = 2 and team_b_id = 1);

그러한 경우에 더 나은 접근 방식이 있습니까?위 쿼리의 경우 team_a_id와 team_b_id 조합의 인덱스를 포함하는 것이 맞습니까?하지만 그럼에도 불구하고 AB OR BA 사이에는 여전히 논리적 OR 조건이 있습니다.

대안으로, 또 다른 아이디어가 있습니다. 또 다른 테이블이있는 것입니다.

History -> team_hash, match_id

나는 수동으로 team_hash를 구축합니다. hash(a,b) == hash(b,a).그러나 이로 인해 삽입 속도가 약간 느려지지만 읽기 속도는 빨라집니다.아니면 정말 더 빨리 읽히나요?

도움이 되었습니까?

해결책

복합 인덱스가 있다고 가정합니다. {team_a_id, team_b_id}, DBMS는 두 개의 인덱스 검색(하나는 team_a_id = 1 and team_b_id = 2 그리고 다른 하나는 team_a_id = 2 and team_b_id = 1), 매우 빠릅니다.나는 당신이 성능이 부족하다고 생각하지 않을 것이라고 기대합니다.


그러나 이러한 인덱스 검색 중 하나를 제거하는 방법이 있습니다.제약 조건 추가...

CHECK(team_a_id < team_b_id)

...그리고 "방향"을 인코딩합니다(예:어떤 팀이 호스트인지)를 필요한 경우 별도의 필드에 입력하세요.이렇게 하면 알잖아요 team_a_id = 2 and team_b_id = 1 절대 사실일 수 없으므로 검색만 하면 됩니다. team_a_id = 1 and team_b_id = 2.


"대칭" 해싱은 좋은 아이디어이지만 다음과 같습니다.

  • 해시의 정확성은 선언적으로 적용할 수 없습니다. 트리거를 통해 또는 애플리케이션 수준에서 적용해야 합니다.
  • 중복된 데이터입니다.당신은 유지해야합니다 team_a_id 그리고 team_b_id 어쨌든 해싱 충돌을 해결하려면.데이터가 클수록 캐시는 작아집니다.
  • 실제로 인덱스 수가 늘어날 수 있습니다. 참조 무결성을 효율적으로 적용하려면 인덱스가 필요할 수 있습니다. team_a_id 그리고 team_b_id 실제 SQL 쿼리에는 필요하지 않더라도 마찬가지입니다.캐시에 더 많은 압력을 가하는 것 외에도 모든 추가 인덱스를 유지해야 하므로 INSERT/UPDATE/DELETE 성능이 저하될 수 있습니다.클러스터링을 끌 수 없는 InooDB의 상황은 특히 심각하므로 보조 인덱스는 힙 기반 테이블보다 비용이 더 많이 드는 경향이 있습니다("클러스터링의 단점" 참조). 이 기사).

다른 팁

어디에서

와 같은 Where 절을 만들 수도 있습니다.
((team_a_id = 1 and team_b_id = 2) or (team_a_id = 2 and team_b_id = 1))
AND team_a_id IN (1,2) AND team_b_id IN (1,2)
.

team_a_id, team_b_id와 같은 색인을 사용할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top