하위 조회 로 반복 되 지 않 는 항목 을 계산 하여 50 배 가속 합 니 다!

본 논문 에서 말 한 이 기술 은 통용 되 지만 설명 을 위해 우 리 는 PostgreSQL 을 선택 했다.pgAdmin III 가 제공 한 해석 적 인 삽화 에 감 사 드 립 니 다. 이 삽화 들 은 큰 도움 이 됩 니 다.
쓸모 는 있 지만 느리다
반복 되 지 않 는 숫자 를 계산 하 는 것 은 SQL 분석의 재난 이다. 분명히 우 리 는 첫 번 째 박문 에서 토론 해 야 한다.
우선, 우 리 는 큰 데이터 세트 가 있 고 정확 하지 않 은 것 을 용인 할 수 있다.HyperLogLog 와 같은 확률 통계 기 는 당신 의 첫 번 째 선택 일 수 있 습 니 다. (우 리 는 앞으로 블 로그 에서 HyperLogLog 에 대해 이야기 할 것 입 니 다) 하지만 빠 르 고 정확 한 결 과 를 추구 하려 면 하위 조회 방법 은 많은 시간 을 절약 할 것 입 니 다.
간단 한 검색 어 부터 시작 합 시다. 어떤 dashboard 사용자 가 가장 자주 방문 합 니까?
select
  dashboards.name, 
  count(distinct time_on_site_logs.user_id)
from time_on_site_logs 
join dashboards on time_on_site_logs.dashboard_id = dashboards.id
group by name
order by count desc

우선 userid 와 dashboardid 에 효율 적 인 색인 이 있 고 로그 줄 수 는 user 보다 많 습 니 다.id 와 dashboardid 가 많다.
천만 줄 의 데이터 만 있 으 면 검색 어 를 조회 하 는 데 48 초가 걸 렸 다.왜 그런 지 알 아 요?우리 명료 한 도 해 를 좀 봅 시다.
느 린 이 유 는 데이터 베 이 스 는 dashboards 표 와 logs 표 의 모든 기록 을 옮 겨 다 니 고 JOIN 작업 을 한 다음 에 정렬 한 다음 에 실제 필요 한 그룹 과 집합 작업 을 해 야 하기 때 문 입 니 다.
먼저 모 은 다음 에 데이터 시트 를 결합 합 니 다.
그룹 을 나 누고 모 은 후에 모든 데이터 베 이 스 를 조작 하 는 대가 가 작 아 졌 다. 왜냐하면 데이터 의 수량 이 작 아 졌 기 때문이다.그룹 을 나 누고 모 을 때 dashboards. name 이 필요 하지 않 기 때문에 JOIN 작업 전에 모 으 기 작업 을 할 수 있 습 니 다.
select
  dashboards.name,
  log_counts.ct
from dashboards
join (
  select
    dashboard_id,
    count(distinct user_id) as ct
  from time_on_site_logs 
  group by dashboard_id
) as log_counts 
on log_counts.dashboard_id = dashboards.id
order by log_counts.ct desc

문 구 는 24 초 동안 실행 되 어 2.4 배의 성능 을 향상 시 켰 다.다시 한 번 살 펴 보면 도 해 는 원인 을 분명하게 밝 힐 수 있다.
우리 가 예 상 했 던 것 처럼 join 작업 전에 group - and - aggregate 작업 을 했 습 니 다.빨리 올 라 가, 우 리 는 timeon_site_logs 표 에 색인 을 추가 합 니 다.
첫 번 째 단 계 는 당신 의 데 이 터 를 작 게 합 니 다.
우 리 는 더 잘 할 수 있 습 니 다. 로그 시트 를 group - and - aggregate 로 작업 할 때 우 리 는 무관 한 데 이 터 를 처 리 했 습 니 다. 사실은 필요 하지 않 습 니 다.우 리 는 각 그룹 에 해시 집합 을 만 들 수 있 습 니 다. 그러면 모든 해시 통 에서 모든 dashboardid 처리 할 데 이 터 를 선택 합 니 다.
그렇게 많은 일 을 할 필요 가 없다. 단지 하 쉬 하나 로 집합 하면 우 리 는 먼저 중복 되 는 값 을 제거 할 수 있다.그리고 우 리 는 이 결과 에 있어 서 집합 조작 을 한다.
select
  dashboards.name,
  log_counts.ct
from dashboards 
join (
  select distinct_logs.dashboard_id, 
  count(1) as ct
  from (
    select distinct dashboard_id, user_id
    from time_on_site_logs
  ) as distinct_logs
  group by distinct_logs.dashboard_id
) as log_counts 
on log_counts.dashboard_id = dashboards.id
order by log_counts.ct desc

우 리 는 무 거 운 것 과 조 를 나 누 어 한 걸음 한 걸음 진행 하여 두 단계 로 나 누 었 다.먼저 (dashboard id, user id) 를 맞 춘 다음 에 이 를 바탕 으로 간단 하고 빠 른 그룹 계산 작업 을 하고 JOIN 작업 은 마지막 에 합 니 다.
최종 효 과 를 알 아 보 자. 총 0.7 초, 지난번 의 28 배, 최초의 68 배.
일반적으로 데이터 크기 와 데이터 위 치 는 매우 중요 합 니 다. 표 의 속성 필드 의 수 치 는 상대 적 으로 적 기 때문에 그렇게 뚜렷 한 효 과 를 가 집 니 다. 데이터 총량 과 비교 하면 (user id, dashboard id) 의 서로 다른 값 이 매우 적 습 니 다.서로 다른 값 이 많 을 수록 각 줄 의 데이터 가 분산 되 기 때문에 조 를 나 누고 계산 하 는 데 시간 이 오래 걸 릴 수록 과연 세상 에 공짜 로 먹 는 점심 은 없다.
다음 에 반복 되 지 않 는 결 과 를 계산 하 는 데 하루 가 걸 릴 지도 모 르 니, 하위 조회 방법 으로 부 하 를 줄 여 보 세 요.
당신들 은 누구 입 니까?
SQL 데이터 분석 을 더 빨리 할 수 있 는 Periscope 를 만 들 었 습 니 다.우 리 는 여기에서 우리 의 도구 에 포 함 된 알고리즘 과 기술 을 공유 합 시다.당신 은 우리 의 홈 페이지 에 등록 하여 우리 의 새로운 고객 으로서 우 리 는 당신 에 게 관련 사항 을 통지 할 수 있 습 니 다.
Use Subqueries to Count Distinct 50X Faster

좋은 웹페이지 즐겨찾기