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中的慢子查询的主要内容,如果未能解决你的问题,请参考以下文章