MySQL JOINs는 어떤 순서로 평가됩니까?
다음과 같은 문의 사항이 있습니다.
SELECT c.*
FROM companies AS c
JOIN users AS u USING(companyid)
JOIN jobs AS j USING(userid)
JOIN useraccounts AS us USING(userid)
WHERE j.jobid = 123;
다음과 같은 질문이 있습니다.
- USING 구문이 ON 구문과 동의어입니까?
- 이 접합부는 왼쪽에서 오른쪽으로 평가됩니까?즉, 이 쿼리는 x = 회사 JOIN 사용자, y = x JOIN 작업, z = y JOIN 사용자 계정,
- 질문 2에 대한 답변이 '예'인 경우, 회사 표에 회사 ID, 사용자 ID 및 jobid 열이 있다고 가정해도 무방합니까?
- 가명 "j"를 언급할 때 WHERE 조항이 어떻게 회사 테이블의 행을 선택할 수 있는지 이해할 수 없습니다.
어떤 도움이라도 주시면 감사하겠습니다!
USING (field name)은 표 1의 약자입니다.필드 이름 = 표2.필드 이름
언어의 특성이 아니기 때문에 SQL은 JOINS가 수행되는 'Order'를 정의하지 않습니다.분명히 순서는 문장에 명시되어야 하지만, INNER JOIN은 대체적인 것으로 간주될 수 있습니다. 순서에 상관없이 나열할 수 있고 동일한 결과를 얻을 수 있습니다.
즉, SELECT ... JOIN을 구성할 때, 특히 좌측 JOIN을 포함하는 JOIN을 구성할 때, 저는 세 번째 JOIN을 첫 번째 JOIN의 결과에 새로운 테이블을 결합하는 것으로 간주하고, 네 번째 JOIN을 두 번째 JOIN의 결과에 결합하는 것으로 간주하는 것이 타당하다는 것을 알았습니다.
더 드물게는 지정된 순서가 휴리스틱에 영향을 미치는 방식으로 인해 쿼리 최적화기의 동작에 영향을 미칠 수 있습니다.
아니요. 쿼리를 조립하는 방법은 회사와 사용자가 모두 회사 ID를 가져야 하고, 작업에는 사용자 ID와 작업 ID가 있어야 하며, 사용자 계정에는 사용자 ID가 있어야 합니다.그러나 JOIN이 작동하려면 회사 또는 사용자 중 한 곳에서만 사용자 ID가 필요합니다.
WHERE 절은 작업 테이블이 제공하는 열을 사용하여 전체 결과(즉, 모든 JOINed 열)를 필터링합니다.
USING 구문에 대해서는 조금도 대답할 수 없습니다.그것은 이상하네요.항상 ON이라는 문구를 써왔기 때문에 한 번도 본 적이 없습니다.
그러나 JOIN 연산의 순서는 최적화 휴리스틱 시스템을 기반으로 쿼리 계획을 구성할 때 쿼리 최적화기에 의해 동적으로 결정된다는 것을 알려드릴 수 있습니다.
JOIN은 기본 키 필드에서 수행됩니까?그렇다면 쿼리 계획에서 우선 순위가 높습니다.
JOIN은 외국 키 필드에서 수행됩니까?이것도 우선순위가 높습니다.
가입 필드에 인덱스가 있습니까?그렇다면 우선순위를 정하세요.
WHERE 절의 필드에 대해 JOIN 작업을 수행합니까?WHERE 절 식을 테이블 스캔을 수행하는 대신 인덱스를 검사하여 평가할 수 있습니까?이것은 중요한 최적화 기회이므로 우선 순위가 가장 높은 범프를 얻게 됩니다.
연결된 열의 카디널리티는 얼마입니까?카디널리티가 높은 열은 옵티마이저가 잘못된 일치(WHERE 절 또는 ON 절을 만족하지 않는 일치)를 식별할 수 있는 기회를 더 많이 제공하므로, 일반적으로 하이 카디널리티 조인은 로우 카디널리티 조인 전에 처리됩니다.
결합된 테이블에 실제 행이 몇 개 있습니까?100개의 값만 있는 테이블에 결합하는 것이 천만 개의 행이 있는 테이블에 결합하는 것보다 데이터 폭증 효과가 적습니다.
아무튼...요점은...쿼리 실행 계획에 들어가는 변수는 많습니다.MySQL이 쿼리를 최적화하는 방법을 보려면 EXPRESP 구문을 사용합니다.
그리고 여기 읽을만한 좋은 기사가 있습니다.
http://www.informit.com/articles/article.aspx?p=377652
편집 중:
네 번째 질문에 대답하기"회사" 테이블을 조회하는 것이 아닙니다.당신은 당신의 FROM과 USING 절에 있는 네 개의 테이블의 결합된 교차 산물을 모두 조회하고 있습니다.
"j.jobid" 별칭은 조인된 테이블 모음에 있는 열 중 하나의 정규화된 이름일 뿐입니다.
MySQL에서는 쿼리 최적화자에게 다음과 같은 작업을 수행할 계획이 있는지 묻는 것이 흥미롭습니다.
EXPLAIN SELECT [...]
여기에 더 자세한 답변이 있습니다.JOIN우선 순위당신의 경우,JOINs는 모두 교환입니다.그들이 없는 곳에서 한번 해봅시다.
스키마 빌드:
CREATE TABLE users (
name text
);
CREATE TABLE orders (
order_id text,
user_name text
);
CREATE TABLE shipments (
order_id text,
fulfiller text
);
데이터 추가:
INSERT INTO users VALUES ('Bob'), ('Mary');
INSERT INTO orders VALUES ('order1', 'Bob');
INSERT INTO shipments VALUES ('order1', 'Fulfilling Mary');
쿼리 실행:
SELECT *
FROM users
LEFT OUTER JOIN orders
ON orders.user_name = users.name
JOIN shipments
ON shipments.order_id = orders.order_id
결과:
Bob 행만 반환됩니다.
분석:
이 쿼리에서LEFT OUTER JOIN먼저 평가를 받았고 그리고JOIN다음의 복합적인 결과를 평가하였습니다.LEFT OUTER JOIN.
두번째 쿼리:
SELECT *
FROM users
LEFT OUTER JOIN (
orders
JOIN shipments
ON shipments.order_id = orders.order_id)
ON orders.user_name = users.name
결과:
Bob의 행 하나(이행 데이터 포함)와 이행 데이터의 NULL이 있는 Mary의 행 하나.
분석:
괄호가 평가 순서를 변경했습니다.
또한 MySQL 문서는 https://dev.mysql.com/doc/refman/5.5/en/nested-join-optimization.html 에서 볼 수 있습니다.
http://dev.mysql.com/doc/refman/5.0/en/join.html 참조
그리고 여기서 읽기 시작합니다.
MySQL 5.0.12의 처리 변경 사항 참여
MySQL 5.0.12부터는 외부 조인 변형을 포함하여 USING으로 자연스러운 조인 및 조인이 SQL:2003 표준에 따라 처리됩니다.목표는 내추럴 조인(NATURAL JOIN) 및 조인(JOIN)에 대한 MySQL의 구문 및 의미론을 정렬하는 것이었습니다.SQL:2003에 따라 사용.그러나 조인 처리의 이러한 변경 사항으로 인해 일부 조인에 대해 다른 출력 열이 발생할 수 있습니다.또한 이전 버전에서 올바르게 작동하는 것으로 보이는 일부 쿼리는 표준을 준수하기 위해 다시 작성해야 합니다.
이러한 변화에는 크게 다섯 가지 측면이 있습니다.
MySQL이 NATURAL 또는 USING 조인 연산의 결과 열을 결정하는 방법(따라서 전체 FROM 절의 결과).
SELECT * 및 SELECT tbl_name 확장.* 선택한 열 목록으로 이동합니다.
NATURAL 또는 USING 조인의 열 이름 해상도.
내추럴(NATURAL) 또는 USING(USING)의 join injoin...온.
조인 조건에서 열 이름 확인...온.
ON vs USING 부분에 대해서는 잘 모르겠습니다 (이 웹사이트에서는 동일하다고 하지만)
주문 질문의 경우, 전체 구현(그리고 아마도 쿼리)에 특정적입니다.MYSQL은 요청을 컴파일할 때 오더를 선택할 가능성이 높습니다.특정 주문을 적용하려면 쿼리를 '네스트'해야 합니다.
SELECT c.*
FROM companies AS c
JOIN (SELECT * FROM users AS u
JOIN (SELECT * FROM jobs AS j USING(userid)
JOIN useraccounts AS us USING(userid)
WHERE j.jobid = 123)
)
파트 4: 여기서 조항은 JOIN을 적용할 수 있는 작업 테이블의 행을 제한합니다.따라서 일치하는 사용자 ID로 인해 가입할 행이 있지만 올바른 jobid가 없는 경우에는 생략됩니다.
1) 를 사용하는 것은 on과 완전히 같지는 않지만, 두 테이블 모두에 당신이 가입하고 있는 이름과 같은 열이 있는 짧은 손입니다.참조: http://www.java2s.com/Tutorial/MySQL/0100__Table-Join/ThekeywordUSINGcanbeusedasareplacementfortheONkeywordduringthetableJoins.htm
제 생각에는 읽기가 더 어렵기 때문에, 저는 가입자의 철자를 적습니다.
3) 이 질문에서 명확하지는 않지만, 아마 그렇지 않을 것입니다.
2) 다른 테이블(회사에 직접 있는 모든 테이블이 아님)을 통해 가입한다고 가정하면 이 쿼리의 순서가 중요합니다.아래 비교 참조:
원본:
SELECT c.*
FROM companies AS c
JOIN users AS u USING(companyid)
JOIN jobs AS j USING(userid)
JOIN useraccounts AS us USING(userid)
WHERE j.jobid = 123
제가 생각하기에 그것은 다음과 같습니다.
SELECT c.*
FROM companies AS c
JOIN users AS u on u.companyid = c.companyid
JOIN jobs AS j on j.userid = u.userid
JOIN useraccounts AS us on us.userid = u.userid
WHERE j.jobid = 123
당신은 여기서 일자리와 사용자 계정에 가입하는 라인을 바꿀 수 있습니다.
모든 것이 회사에 합류한다면 어떤 모습일까요?
SELECT c.*
FROM companies AS c
JOIN users AS u on u.companyid = c.companyid
JOIN jobs AS j on j.userid = c.userid
JOIN useraccounts AS us on us.userid = c.userid
WHERE j.jobid = 123
이건 정말 논리적으로 말이 안 돼요각 사용자가 자신의 회사를 가지고 있지 않는 한.
4.) sql의 마법은 특정 열만 표시할 수 있지만 모든 열은 정렬 및 필터링을 위한 것입니다.
당신이 돌아온다면
SELECT c.*, j.jobid....
필터링 중인 내용은 명확하게 알 수 있었지만 데이터베이스 서버는 필터링을 위해 행을 출력하는지 여부를 신경 쓰지 않습니다.
언급URL : https://stackoverflow.com/questions/228424/in-what-order-are-mysql-joins-evaluated
'programing' 카테고리의 다른 글
| xml 파일에서 BOM 문자를 제거하려면 어떻게 해야 합니까? (0) | 2023.10.19 |
|---|---|
| 워드프레스에서 프로그래밍 방식으로 사용자 아바타 변경 (0) | 2023.10.19 |
| Excel VBA에서 COM interop에 대한 관리 권한이 없는 regasm 호출 (0) | 2023.10.19 |
| 오라클에서 날짜 시간 쿼리 (0) | 2023.10.19 |
| django와 wsgi로 하위 디렉토리에서 워드프레스 블로그 제공 (0) | 2023.10.19 |