MySQL中的慢子查询

Posted

技术标签:

【中文标题】MySQL中的慢子查询【英文标题】:Slow subquery in MySQL 【发布时间】:2011-07-28 19:18:18 【问题描述】:

我正在尝试使用 CodeIgniter 和 Datatables.net 生成报告。

现在我正在尝试关闭工作的数量(它是一个人力资源系统)。我曾经查询所有作业,并在 php 中执行 foreach,然后进行计算。

因为我想使用 Datatables 的所有功能(专门排序)我试图在 mysql 中进行所有计算。

问题是:第二个子查询非常非常非常慢。

SELECT 
jobs.jobs_id, clients.nome_fantasia, concat_ws(' ', user_profiles.first_name, user_profiles.last_name) as fullname, 
jobs.titulo_vaga, jobs.qtd_vagas, company.name as nome_company, jobs_status.name as      status_name, DATEDIFF(NOW(), jobs.data_abertura) as date_idade, 
(select count(job_cv.jobs_id) from job_cv where job_cv.jobs_id = jobs.jobs_id) as qtd_int,
(select count(distinct job_cv.user_id) from job_cv_history join job_cv on job_cv.job_cv_id = job_cv_history.job_cv_id where job_cv_history.status = '11' and job_cv.jobs_id = jobs.jobs_id ) as fechadas 
FROM (jobs)
JOIN clients ON lients.clients_id=jobs.clients_idJOIN user_profiles ON jobs.consultor_id=user_profiles.user_id
JOIN jobs_status ON jobs.status=jobs_status.jobs_status_id 
JOIN company ON jobs.company_id=company.company_id 
LIMIT 50

有人可以帮助我吗?如果需要,我可以提供更多信息。

更新

使用 JOIN 而不是 SELECT 的想法适用于第一个子查询,但第二个子查询不适用,有没有办法传递一个“变量”以在子查询中使用?喜欢当前的 jobs_id?

再次更新

这条线本身就可以正常工作。但是在子查询中需要大约一分钟的磨损值

SELECT job_cv.jobs_id,count(distinct job_cv.user_id) AS fechadas
FROM job_cv_history 
JOIN job_cv 
ON job_cv.job_cv_id = job_cv_history.job_cv_id 
WHERE job_cv_history.status = '11'
GROUP BY job_cv.jobs_id

【问题讨论】:

【参考方案1】:

慢的不是子查询。事实上,您正在为从外部查询返回的每一行执行这些子查询。将这些移动到连接中,您应该会发现性能有所提高。

SELECT 
  jobs.jobs_id, clients.nome_fantasia, concat_ws(' ', user_profiles.first_name, user_profiles.last_name) as fullname, 
jobs.titulo_vaga, jobs.qtd_vagas, company.name as nome_company, jobs_status.name as      status_name, DATEDIFF(NOW(), jobs.data_abertura) as date_idade, 
qtd.qtd_int,
fechadas.fechadas 
FROM (jobs)
JOIN clients ON lients.clients_id=jobs.clients_idJOIN user_profiles ON jobs.consultor_id=user_profiles.user_id
JOIN jobs_status ON jobs.status=jobs_status.jobs_status_id 
JOIN company ON jobs.company_id=company.company_id 
JOIN (
  SELECT jobs_id, count(jobs_id) AS qtd_int FROM job_cv GROUP BY jobs_id
) AS qtd ON qtd.jobs_id = jobs.jobs_id
JOIN (
  SELECT job_cv.user_id, count(distinct job_cv.user_id) AS fechadas
  FROM job_cv_history 
  JOIN job_cv 
  ON job_cv.job_cv_id = job_cv_history.job_cv_id 
  WHERE job_cv_history.status = '11'
  GROUP BY job_cv.user_id
) AS fechadas ON job_cv.jobs_id = jobs.jobs_id
LIMIT 50

【讨论】:

Tkz...我想出了这个来工作:@ 987654321@第一个加入qtd很好...但是第二个...我只得到了fechadas的总数...而我需要每个工作的总数。请问有什么想法吗?【参考方案2】:

您可以尝试创建这些索引:

ALTER TABLE `job_cv` ADD INDEX `job_cv_cindex` (`job_cv_id` ASC, `jobs_id` ASC, `user_id` ASC);
ALTER TABLE `job_cv_history` ADD INDEX `job_cv_history_cindex` (`job_cv_id` ASC, `status` ASC);

【讨论】:

刚刚做了,同一时间。你能解释一下为什么索引会有所帮助吗?【参考方案3】:

使用联接而不是子查询。它显着提高了 MySql 的性能。 尝试在您的情况下使用左连接,看看性能是否有所提高

【讨论】:

以上是关于MySQL中的慢子查询的主要内容,如果未能解决你的问题,请参考以下文章

生产慢查询记录:MySQL IN 子查询导致的慢查询

phpMyAdmin中的慢查询但Mysql慢查询日志文件中没有[关闭]

markdown 删除Mysql中的慢查询日志

mysql中的慢查询会不会影响速度

说说 MySQL 子查询

使用MySQL的慢查询日志找到低效的SQL语句