2015-01-27 2 views
1

Google BigQuery에서 버그를 발견했지만 확실하지 않습니다. 누군가가 대안을 제시 할 수 있기를 희망합니다.여러 조인을 사용하는 이유는 무엇입니까?

테이블 나는 200K의 데이터만을 가진 테이블에서 실행하고 있습니다.

이 ~ 삼초한다 : 나는 다음과 같은 기괴한 행동을 우연히 깔때기 분석 할 내 시도에

SELECT 
    COUNT(DISTINCT Q0._user_id) AS step0 
FROM 
    (SELECT _user_id FROM [5629499534213120.201501]) AS Q0 
LEFT OUTER JOIN 
    (SELECT _user_id, _time FROM [5629499534213120.201501] WHERE _os=='Windows') AS Q1 
ON (Q0._user_id=Q1._user_id) 

~ 3 분 정도 소요을 :

SELECT 
    COUNT(DISTINCT Q0._user_id) AS step0 
FROM 
    (SELECT _user_id FROM [5629499534213120.201501]) AS Q0 
LEFT OUTER JOIN 
    (SELECT _user_id, _time FROM [5629499534213120.201501] WHERE _os=='Windows') AS Q1 
ON (Q0._user_id=Q1._user_id) 
LEFT OUTER JOIN 
    (SELECT _user_id, _time FROM [5629499534213120.201501] WHERE _country=='de') AS Q2 
ON (Q0._user_id=Q2._user_id) 

의미 하나 더 왼쪽 결합을 추가하면 쿼리가 믿을 수 없을 정도로 느려집니다 (데이터는 약 200k에 불과합니다). 당신이 주요 문제에 초점을 맞출 수 있도록

분명히, 내가 선택 문을 단순화 (내가 사용하는 실제 SELECT 문은 훨씬 더 복잡하다)

사람이 문제, 또는에 대한 해결 방법 무엇을 알고 있나요?

+2

LEFT OUTER JOIN [5629499534213120.201501] AS Q2 ON (Q0._user_id = Q2._user_id 및 Q2._country == 'de')'이 발생하면 어떻게됩니까? 나는 당신의 내부 질의가 인덱스를 사용할 수있는 능력을 깨뜨릴 수 있다고 생각한다. –

+0

"ON 절은 각 테이블의 한 필드 이름과 테이블 이름 앞에 접두사가 붙은 모든 필드 이름을 비교해야한다." – shaylevi2

+0

좋아요, Q2._country == 'de'를 WHERE 절로 옮기는 것은 어떨까요? –

답변

5

가 나는 경우 BigQuery 이슈 트래커에 응답,하지만 난 여기에 내 대답을 다시 게시 해요 :

가 나는 BigQuery의 엔지니어와 나는 우리의 로그에 쿼리를 보였다. 보고있는 것은 가입 폭발입니다.

고유하지 않은 키를 사용하여 3- 방향 자체 조인을 수행했습니다. 필드 "_user_id"는 왼쪽에 3937 개의 행, 첫 번째 조인에서 1388 개의 행 및 두 번째 조인에서 1388 개의 행과 일치하는 단일 값을가집니다.

즉, 3937 * 1388 * 1488 또는 75 억 개의 출력 행을 생성합니다. (그런 다음 출력 크기를 줄이기 위해 개수를 구분했지만 중간 값을 먼저 만들어야했습니다.)

75 억 개의 중간 행을 생성하는 데는 몇 분이 걸릴 것이라고 생각하지 않습니다. 특히 모든 행이 단일 키에서 생성되었으므로 단일 작업자 작업으로 생성되어야했습니다.

제 생각 엔 조인 폭발을 피하기 위해 쿼리를 다시 구성 할 수 있습니다.

+0

안녕하세요 요르단, 대단히 감사합니다. :). 문제 추적기에서 계속 진행하기 바랍니다. 어쩌면 (제발?) 당신이 쿼리를 재구성하도록 도울 수 있습니다, 나는 사람들이 참조 할 수 있도록 여기에 수정 된 쿼리를보고 할 것입니다. – shaylevi2

+0

다음은 원하는 사람을위한 링크입니다. https://code.google.com/p/google-bigquery/issues/detail?id=213 – shaylevi2

0

BigQuery에 익숙하지 않지만 내부 쿼리 (SELECT _user_id, _time FROM [...)가 전체 테이블을 검색하고있는 것으로 생각됩니다.

다음과 같이 쿼리를 새로운 표현에 대해 무엇 :

SELECT 
    COUNT(DISTINCT Q0._user_id) AS step0 
FROM 
    [5629499534213120.201501] AS Q0 
LEFT OUTER JOIN [5629499534213120.201501] AS Q1 
    ON (Q0._user_id=Q1._user_id) 
LEFT OUTER JOIN [5629499534213120.201501] AS Q2 
    ON (Q0._user_id=Q2._user_id) 
WHERE Q1._os=='Windows' 
    AND Q2._country=='de' 

를 지금까지 내가 말할 수있는, 결과는 동일해야합니다; 이것은 데이터베이스가 인덱스를 사용하도록 허용해야합니다 (데이터베이스가 적절하게 표준화 된 경우).

+0

결과는 복잡한 선택 문의 경우와 같지 않을 수 있습니다. 목적은 유입 경로를 만드는 것입니다. (step0, step1, step2) 다른 단계, 다른 조건. – shaylevi2

+0

나는 그것이 "폭발에 가담"을 일으키는 깔대기라고 생각합니다. 개인 선택으로 데이터베이스 선택이 현명하지 않게됩니다. –

관련 문제