2009-06-05 147 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子句将其链接到外部查询?我在这里错过了什么吗?