2010-05-11 6 views
0

나는 의심의 여지가있다. R과 S가 각각 속성 A와 B와 2 개의 관계라고 가정합니다. 내가 쿼리가있는 경우MySQL의 where 절은 어떻게 작동합니까?

Select * 
From R, S 
Where R.A = S.B 

네, 말의 C 또는 C++

For(i=0; i<n; i++) 
    For(j=0; j<n; j++) 
     if (i == j) 
      //DO some work 
+4

이는 SQL * *에 대한 오해를 반영합니다. SQL의 핵심은 원하는 결과의 성격을 설명하고, 기본 SQL 엔진은 결과 집합을 가장 효율적으로 만드는 쿼리 계획을 설계한다는 것입니다. 계획의 모양은 쿼리가 실행될 때마다 다를 수있는 통계 및 인덱스에 따라 달라집니다. 짧은 버전은 "귀하의 테이블이 적절하게 색인되어 있으면 아니오"입니다. –

답변

2

우선 : mysql이 내부적으로 어떻게 될지 전혀 알지 못합니다 mysql의 내부 구조를 모르고 쿼리를 최적화한다. 순수 관계형 데이터베이스의 즉

, 이것은 당신이하고있는 일입니다 :

SELECT * FROM R, S -> 모든 (R, S) 튜플을 생성하는 크로스 조인을 수행합니다.

WHERE R.A = S.B -> 지금 그래서 모든 튜플을 가서 것이 동작

이 그 튜플을 선택 (더 많거나 적은 코드와 같은). 그러나 mysql은 모든 튜플을 결코 생성하지 않는보다 효율적인 내부 조인으로 이것을 내부적으로 줄이는 것이 가능하지만 R.A=S.B이 유효한 튜플 만 완벽하게 가능합니다.

+0

MySQL이 쿼리를 최적화하는 방법을 알기를 바랍니다. 결정 론적이지, 안 그래? 따라서 MySQL 내부에 대해 잘 알고있는 사람이라면 MySQL이하는 일을 설명 할 수 있어야합니다. 그리고 그것은 오픈 소스입니다, 맞죠? 충분히 헌신적 인 사람은 프로그램을 공부하고 MySQL이하는 일을 배울 수 있어야합니다. –

+0

네, 구현을 안다면 당신은 그것을 알 수 있습니다 :). – KillianDS

+0

@Rob Kennedy : MySQL이 무엇을 할 것인가를 분명히 알 수있는 방법이 있습니다 - EXPLAIN SELECT. 질의를보고 인덱스를 아는 것만으로도 MySQL이 어떤 일을 할 것인지 추측 할 수는 있지만 여전히 잘못 될 수 있습니다. MySQL은 실제로 쿼리 자체뿐만 아니라 테이블 내부의 데이터 분포를 조사 할 것이고 데이터가 변경되면 다른 시간에 다른 결정을 내릴 수 있습니다. –

1

기능이 많다는에서 For 루프를 두 번 같은이 작업을 수행합니다. 그것이 작동하는 방법입니다. 중첩 된 for 루프에서 두 테이블의 모든 행을 반복하며 상응하는 필드 만 선택한다고 상상할 수 있습니다.

상황에 따라 상황이 매우 다릅니다. 데이터베이스 엔진은 많은 종류의 최적화를 사용하여 쿼리 속도를 높입니다. 데이터베이스 엔진이 쿼리를 실제로 실행하는 방법은 데이터베이스 엔진의 유형, 매우 중요한 인덱스, 데이터 양 등과 같은 많은 요소에 따라 달라집니다.

2

네, 적어도 개념적으로는 그렇습니다. 조인은 두 테이블에서 요소의 데카르트 십자가를 만듭니다.이 두 요소는 두 개의 루프를 사용하여 수행하고 있으며 Where 절은 조건이 참인 데카르트 십자가의 멤버로 제한됩니다. 물론 구현은 실제로 전체 데카르트 십자가를 만들지는 않을 것입니다. 모든 pairwise 비교를 거치지 않고 색인을 사용하여 일치 항목을 식별합니다.

2

이러한 속성 중 하나에 색인이없는 경우 정확히 MySQL이 수행해야하는 것이며 매우 비효율적 일 수 있습니다.

색인을 사용하면 전 세계에서 모든 차이가 있습니다. SB에 대한 인덱스가있을 경우, 예를 들면, 다음의 MySQL이 같은 더 많은 것을 할 수있다 : 인덱스 대신 RA에 있는지

for (i=0; i<n_r; i++) { // loop over all rows in R 
    matching_rows = retrieve_from_index_s_b(i); // very fast operation, like direct array access 
    for (j=0; j<matching_rows.length(); j++) 
     // do some work 
} 

마찬가지로, 다음 외부 루프는 S의 행에있을 것, 및 내부 루프는 R에서 일치하는 행에있을 것입니다.

모두 속성에 대한 인덱스가있는 경우 MySQL은 각 테이블의 데이터 양을 살펴보고 루프를 구성하여 작업량을 최소화합니다. 필수. 이것은 MySQL 쿼리 최적화 프로그램의 일이며 필요한 테이블 액세스 수를 최소화하기 위해 테이블을 확인하기위한 적절한 순서를 결정하기 위해 많은 작업을 수행 할 수 있습니다.

다른 사람들이 이미 언급했듯이 SQL은 기본적으로 선언적 언어입니다. SQL은 주로 데이터베이스에서 결과를 가져 오는 방법을 지정하지 않고 원하는 결과 만 말합니다. 데이터베이스가 결과를 시각화하는 데 도움이되는 경우 중첩 루프의 전체 집합을 항상 수행하고 있다고 가정 할 수 있지만 인덱스를 올바르게 설정하면 일반적으로 더 똑똑한 작업을 수행하게됩니다.

+0

+1을 사용하여 색인 사용의 영향을 보여줍니다. – MJB

1

설명하는 내용은 nested loops 가입 전략입니다. 옵티마이 저는이 또는 다른 조인 전략을 선택할 수 있습니다 (사용 가능한 옵션은 RDBMS here is a summary of some common join algorithms에 따라 다름).

어느 것이 선택되는지는 데이터가 이미 정렬되었는지, 사용 가능한 메모리의 양, 테이블의 크기, 인덱스의 사용 가능 여부 등과 같은 JOIN 조건 (일부는 등호 인 경우에만 작동) 등 다양한 문제에 따라 달라집니다.