가장 가능성있는 설명은 옵티마이 저가 선택한 실행 계획이 효율적이지 않다는 것입니다.
표시되지 않는 것은이 테이블에서 사용할 수있는 색인입니다. 쿼리에 대해 눈에 띄는
것은 이것이다 :
WHERE b.yearID - m.birthYear = '35'
MySQL이 때문에 (같은 player_id로 batting
에서 모든 행에 그 주어진 player_id와 master
에서 모든 행을 가지고 일치하는 것입니다 평등 가입 조건)
ON m.playerID = b.playerID
그리고 MySQL이 가지고 결합 행의 설정을 한 다음이 표현
을 계산
그런 다음 그 결과를 '35'와 비교하십시오.
playerID
열이 master
테이블 우리는 (playerID,yearID)
의 열을 선도하는 것을 batting
에 인덱스를 활용할 수있는 형태로 작성된 쿼리 조건을보고 선호하는 것
에서 고유이라고 가정.
SELECT b.playerid
, b.yearid
, SUM(b.hr) AS hr
FROM master m
JOIN batting b
ON b.playerid = m.playerid
AND b.yearid = m.birthyear + 35
GROUP BY b.playerid, b.yearid
HAVING SUM(b.hr) > 500
ORDER BY SUM(b.hr) DESC
각 플레이어에 대해 반환되는 행을 가져 오려면 GROUP BY
절이 필요합니다. 총 홈런을 얻으려면 SELECT 목록에 SUM() 집계가 필요합니다. playerid
는 master
테이블에 고유하지 않으면
쿼리의 최적의 성능을
, 당신이 포함하는 인덱스
... ON batting (playerid, yearid, hr)
을 싶어, 다음 쿼리는 당신이 기대하는 가치를 보장하지 않을 SUM (b.hr)이면 예상되는 값의 double, triple 등이 될 수 있습니다.
실행 계획을 보려면 EXPLAIN을 사용하십시오.
또한 실행 계획에 부정적인 영향을 줄 수있는 암시 적 데이터 유형 변환에주의하십시오. 두 테이블의 playerid
열의 데이터 유형이 일치하고 yearid
및 birthyear
열의 데이터 유형이 숫자라고 가정합니다.
편집
내 원래 대답이 쿼리는 "시간 초과"이유에 초점을 맞추고, 나는 당신이 달성하고자하는 결과에 대한 사양을 놓친되었습니다 경력을 가지고
반환 선수 총계 500 이상이며 해당 선수 각각에 대해 특정 연도에 년 개의 인적 자원을 반환하십시오.
(I 적절 선수가 35 세를 회전하는 "년"을 결정하는 논의를 따로 설정하고, 원래의 쿼리에서 기준을 사용합니다.)
한 가지 방법은 조건 을 사용하는 것입니다 집합. 조건이 TRUE이면 HR을 반환하는 식을 사용하고 그렇지 않으면 0 또는 NULL을 반환합니다. 그런 다음 해당 식을 SELECT 목록의 SUM 집계로 래핑하십시오.
우리는 모든 선수에 대한 행을 반환하려면 ...
SELECT b.playerid
, MAX(IF(b.yearid = m.birthyear + 35,b.yearid,NULL)) AS yearid
, SUM(IF(b.yearid = m.birthyear + 35, b.hr, 0)) AS year_hr
FROM master m
JOIN batting b
ON b.playerid = m.playerid
GROUP BY b.playerid
HAVING SUM(b.hr) > 500
AND MAX(IF(b.yearid = m.birthyear + 35,b.yearid,NULL)) IS NOT NULL
ORDER BY ...
를 500 이상 경력 인사 총 플레이어 만 행을 반환하고 지정된 연도의 batting
적어도 하나 개의 행을 갖고 싶어 경력 HR이 500을 넘는 경우 batting
에 지정된 yearid
의 행이없는 경우에도 HAVING 절의 두 번째 조건을 생략하도록 쿼리를 조정할 수 있으며 SELECT 목록에서 expression m.birthyear + 35를 사용할 수 있습니다
SELECT b.playerid
, MAX(m.birthyear + 35) AS yearid
, SUM(IF(b.yearid = m.birthyear + 35, b.hr, 0)) AS year_hr
FROM master m
JOIN batting b
ON b.playerid = m.playerid
GROUP BY b.playerid
HAVING SUM(b.hr) > 500
ORDER BY ...
경력 HR 합계가 정확히 500 인 플레이어는 제외됩니다.
힌트 :이 쿼리에는'GROUP BY'가 필요합니다. –
반드시 35 세의 나이는 아니 겠지? – Strawberry
500 HR 클럽의 모든 회원에 대해 35 시즌 HR 총계를 가져 가고 싶습니다. – lmoquin