2009-06-05 160 views
1

嘿傢伙。這是從這個question慢查詢 - 優化幫助

後得到正確的數據,並根據企業的要求作出一些調整後,我現在已經得到了我的手這個小型野獸。該查詢應該返回的新求職者登記總數和新上傳的簡歷數量:

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) 

注: - 在傳遞中從報告模塊參數Unix時間戳功能,這兩個值我們的後端。我每次運行它時,MySQL都會窒息並無聲無息地進入Interweb的以太網。

幫助表示讚賞。

更新:嘿傢伙。非常感謝所有周到和有益的評論。我在這裏只有2周的時間,所以我仍然在學習模式。所以,這個查詢是在一個縮略圖和一個受過教育的猜測之間。現在開始回答你所有的問題。

+0

您必須提供一些有關此查詢中涉及的表的信息......哪些列具有索引等? ...另外,你能否將查詢變得更友好些? – jerryjvl 2009-06-05 07:37:21

+0

你想做什麼?如果您需要優化幫助,您需要爲我們提供您正在使用的模式和索引。 – NicDumZ 2009-06-05 07:37:45

回答

6

tb_cv未連接到子查詢中的其他表。我想這是慢查詢的根本原因。它會導致產生一個笛卡爾積,產生比你可能需要更多的行。

除此之外,我會說你需要tb_jobseeker.created_attb_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 BY值,你不最終的輸出。爲什麼? (我已將分組字段添加到輸出列表
  • 您在子查詢中加入三個表,而只使用其中一個表中的值。爲什麼?除了篩選出沒有求職者或行業附件的CV記錄外,我不認爲它會有什麼好處,但我發現很難想象。 (我已刪除整個子查詢並使用簡單的COUNT代替
  • 您的子查詢每次都返回相同的值。你是否想要以某種方式關聯它,對於這個行業可能?
  • 子查詢爲分組查詢中的每個記錄運行一次,而不包含在聚合函數中。
0

首先,可能需要將'UNIX_TIMESTAMP'轉換移到等式的另一端(也就是對> =和< =的另一端的文字時間戳值執行反轉功能)。這將避免內部查詢必須爲每個記錄執行轉換,而不是爲查詢執行一次轉換。

此外,爲什麼uploaded_cvs查詢沒有任何where子句將其鏈接到外部查詢?我在這裏錯過了什麼嗎?