2009-06-05 5 views
1

안녕 얘들 아. 이 후속 조치입니다. question :느린 쿼리 - 최적화 도움말

올바른 데이터를 얻고 비즈니스 요청에 따라 몇 가지 수정을 한 후에 저는이 소형 짐을 직접 잡았습니다. 보고서 모듈에서 매개 변수로 전달되는 UNIX 타임 스탬프 기능의 두 값 - :

SELECT COUNT(j.jobseeker_id) as new_registrations, 
(
    SELECT 
     COUNT(c.cv_id) 
    FROM 
     tb_cv as c, tb_jobseeker, tb_industry 
    WHERE 
     UNIX_TIMESTAMP(c.created_at) >= '1241125200' 
    AND 
     UNIX_TIMESTAMP(c.created_at) <= '1243717200' 
    AND 
     tb_jobseeker.industry_id = tb_industry.industry_id 
) 
AS uploaded_cvs 
FROM 
    tb_jobseeker as j, tb_industry as i 
WHERE 
    j.created_at BETWEEN '2009-05-01' AND '2009-05-31' 
AND 
    i.industry_id = j.industry_id 
GROUP BY i.description, MONTH(j.created_at) 

참고 :이 쿼리 새로운 구직자 등록의 총 수와 신규 업로드 CV의 수를 반환해야합니다 우리의 백엔드.

나는 그것을 실행할 때마다 MySQL이 질식하고 Interweb의 에테르에 조용하게 자리 잡고있다.

도움을 주시면 감사하겠습니다.

업데이트 : 안녕 얘들 아. 사려 깊고 도움이되는 모든 의견에 감사드립니다. 저는 2 주 밖에 안 남았으므로 아직 스키마를 배우고 있습니다. 그래서,이 쿼리는 엄지 손가락과 교육을받은 추측의 어딘가에 있습니다. 지금 모든 질문에 대답하기 시작할 것입니다.

+0

이 쿼리와 관련된 테이블에 대한 정보를 제공해야합니다. 어떤 열에 인덱스 등이 있습니까? ... 또한 눈에 조금 친숙한 형식으로 쿼리를 구성 할 수 있습니까? – jerryjvl

+0

당신은 무엇을하려고합니까? 최적화에 도움이 필요하면 사용중인 스키마와 인덱스를 제공해야합니다. – NicDumZ

+0

이 cv_id는 무엇인가요? 전체 테이블? 또한 하위 쿼리에서 tb_cv는 tb_jobseeker 및 tb_industry에 조인/연결되지 않습니다. 이 작업을 수행 하시겠습니까? – NicDumZ

답변

6

tb_cv는 하위 쿼리의 다른 테이블에 연결되어 있지 않습니다. 이것은 느린 쿼리의 근본 원인이라고 생각합니다. 카디 전 곱을 생성하여 아마도 필요한 것보다 많은 행을 생성합니다. 그 외에는

난 당신이 tb_jobseeker.created_at, tb_cv.created_attb_industry.industry_id에 인덱스를 필요 말하고 싶지만, 그들이 인덱스의 사용을 방지하기 때문에 당신은 하위 쿼리에서 UNIX_TIMESTAMP() 호출을 제거 할 수 있습니다. 대신 BETWEEN과 실제 필드 값을 사용하십시오.

귀하의 질의를 이해하고 더 나은 버전을 작성하기위한 제 시도입니다.

SELECT 
    i.industry_id, 
    i.description, 
    MONTH(j.created_at)   AS month_created, 
    YEAR(j.created_at)    AS year_created, 
    COUNT(DISTINCT j.jobseeker_id) AS new_registrations, 
    COUNT(cv.cv_id)    AS uploaded_cvs 
FROM 
    tb_cv AS cv 
    INNER JOIN tb_jobseeker AS j ON j.jobseeker_id = cv.jobseeker_id 
    INNER JOIN tb_industry AS i ON i.industry_id = j.industry_id 
WHERE 
    j.created_at BETWEEN '2009-05-01' AND '2009-05-31' 
    AND cv.created_at BETWEEN '2009-05-01' AND '2009-05-31' 
GROUP BY 
    i.industry_id, 
    i.description, 
    MONTH(j.created_at), 
    YEAR(j.created_at) 

쿼리 쓰는 동안 내가 발견 몇 가지 : 당신이 값에 의해 돈을

  • 당신 GROUP을 나는 새 구직자 등록 및 산업 한달 새 업로드 이력서의 수를 얻고 싶은 생각 결국 출력. 왜? (그룹화 된 필드를 출력 목록에 추가했습니다.)
  • 서브 쿼리에 세 개의 테이블을 조인하고 그 중 하나의 값만 사용합니다. 왜? 나는 구직자가없는 CV 기록을 필터링하는 것 외에 다른 어떤 것이 좋을지 모르겠다. 또는 내가 상상하기 어려운 —이 붙어있는 산업. (전체 하위 쿼리를 제거하고 대신 COUNT을 사용했습니다.)
  • 하위 쿼리는 매번 동일한 값을 반환합니다. 어떤 식 으로든 상관 관계가 있을지, 어쩌면 업계와 관련 지어 줄지도 모르겠다.
  • 하위 쿼리는 집계 함수로 래핑되지 않고 그룹화 된 쿼리의 모든 레코드에 대해 한 번 실행됩니다.
+0

+1 사실 tb_cv와 tb_jobseeker에 직교 좌표가 있습니다 –

+0

필자는 SQL에 강하지 않고 시스템에 사용 된 다른 쿼리의 일부를이 항목에 사용했습니다 ... * sheepish * – Midiane

+0

안녕하세요 tomalak, 방금 귀하의 질문을 시도했습니다. 그것은 완벽하게 작동합니다! 감사. 읽기가 쉽고 불쌍한 시도만큼 복잡하지 않습니다. 나는 내가 필요로하지 않는 몇 개의 밭을 벗겼다. 심각하게 고마워. – Midiane

0

먼저 'UNIX_TIMESTAMP'변환을 방정식의 다른 쪽 (즉,> = 및 < =)의 반대쪽에있는 리터럴 타임 스탬프 값에 역으로 수행하는 것이 좋습니다. 그러면 내부 쿼리가 쿼리에 대해 한 번이 아닌 모든 레코드에 대한 변환을 수행하지 않아도됩니다.

또한 왜 uploaded_cvs 쿼리에는 외부 쿼리와 연결되는 where 절이 없습니까? 내가 여기서 뭔가를 놓치고 있니?