使用concat和filesort时,mysql查询速度慢

时间:2018-02-13 15:30:04

标签: mysql performance join concat filesort

除非我在搜索中添加“最近状态”和/或“最近状态(扩展)”,否则此系统上的所有查询都很快。

Candidates Page with Re4cent Status selected

来自慢速日志的查询。

SELECT SQL_CALC_FOUND_ROWS
candidate.candidate_id AS candidateID,
candidate.candidate_id AS exportID,
candidate.is_hot AS isHot,
candidate.date_modified AS dateModifiedSort,
candidate.date_created AS dateCreatedSort,
IF(candidate_joborder_submitted.candidate_joborder_id, 1, 0) AS submitted,
IF(attachment_id, 1, 0) AS attachmentPresent,
candidate.first_name AS firstName,
candidate.last_name AS lastName,
candidate.city AS city,
candidate.state AS state,
candidate.key_skills AS keySkills,
owner_user.first_name AS ownerFirstName,owner_user.last_name AS ownerLastName,CONCAT(owner_user.last_name, owner_user.first_name) AS ownerSort,
DATE_FORMAT(candidate.date_created, '%m-%d-%y') AS dateCreated,
DATE_FORMAT(candidate.date_modified, '%m-%d-%y') AS dateModified,
(
SELECT
CONCAT(
'<a href="index.php?m=joborders&amp;a=show&amp;jobOrderID=',
joborder.joborder_id,
'" title="',
joborder.title,
' (',
company.name,
')">',
candidate_joborder_status.short_description,
'</a>'
)
FROM
candidate_joborder
LEFT JOIN candidate_joborder_status
ON candidate_joborder_status.candidate_joborder_status_id = candidate_joborder.status
LEFT JOIN joborder
ON joborder.joborder_id = candidate_joborder.joborder_id
LEFT JOIN company
ON joborder.company_id = company.company_id
WHERE
candidate_joborder.candidate_id = candidate.candidate_id
ORDER BY
candidate_joborder.date_modified DESC
LIMIT 1
) AS lastStatus
FROM
candidate
LEFT JOIN attachment
ON candidate.candidate_id = attachment.data_item_id
AND attachment.data_item_type = 100
LEFT JOIN candidate_joborder AS candidate_joborder_submitted
ON candidate_joborder_submitted.candidate_id = candidate.candidate_id
AND candidate_joborder_submitted.status >= 400
AND candidate_joborder_submitted.site_id = 1
AND candidate_joborder_submitted.status != 650
LEFT JOIN user AS owner_user ON candidate.owner = owner_user.user_id LEFT JOIN saved_list_entry
ON saved_list_entry.data_item_type = 100
AND saved_list_entry.data_item_id = candidate.candidate_id
AND saved_list_entry.site_id = 1
WHERE
candidate.site_id = 1

GROUP BY candidate.candidate_id

ORDER BY dateModifiedSort DESC
LIMIT 0, 15;

分析结果

'1', 'PRIMARY', 'attachment', 'system', 'IDX_type_id,IDX_data_item_id,dataitem1', NULL, NULL, NULL, '0', 'const row not found'
'1', 'PRIMARY', 'candidate', 'ALL', 'IDX_site_first_last_modified,IDX_site_id_email_1_2', NULL, NULL, NULL, '8645', 'Using where; Using temporary; Using filesort'
'1', 'PRIMARY', 'candidate_joborder_submitted', 'ref', 'IDX_candidate_id,IDX_site_id,IDX_status_special,IDX_site_joborder', 'IDX_candidate_id', '4', 'opencats.candidate.candidate_id', '1', 'Using where'
'1', 'PRIMARY', 'owner_user', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'opencats.candidate.owner', '1', 'Using where'
'1', 'PRIMARY', 'saved_list_entry', 'ref', 'IDX_data_item_type,IDX_data_item_id,IDX_type_id', 'IDX_data_item_id', '4', 'opencats.candidate.candidate_id', '1', 'Using where'
'2', 'DEPENDENT SUBQUERY', 'candidate_joborder', 'index', 'IDX_candidate_id', 'IDX_date_modified', '8', NULL, '1', 'Using where'
'2', 'DEPENDENT SUBQUERY', 'candidate_joborder_status', 'eq_ref', 'PRIMARY,status1', 'PRIMARY', '4', 'opencats.candidate_joborder.status', '1', ''
'2', 'DEPENDENT SUBQUERY', 'joborder', 'eq_ref', 'PRIMARY,order1', 'PRIMARY', '4', 'opencats.candidate_joborder.joborder_id', '1', ''
'2', 'DEPENDENT SUBQUERY', 'company', 'eq_ref', 'PRIMARY,company1,comp1', 'PRIMARY', '4', 'opencats.joborder.company_id', '1', 'Using where'

我认为这是缓慢的部分。

SELECT CONCAT(
'<a href="index.php?m=joborders&amp;a=show&amp;jobOrderID=',
joborder.joborder_id,
'" title="',
joborder.title,
' (',
company.name,
')">',
candidate_joborder_status.short_description,
'</a>'
)
FROM
candidate_joborder
LEFT JOIN candidate_joborder_status
ON candidate_joborder_status.candidate_joborder_status_id = candidate_joborder.status
LEFT JOIN joborder
ON joborder.joborder_id = candidate_joborder.joborder_id
LEFT JOIN company
ON joborder.company_id = company.company_id
WHERE
candidate_joborder.candidate_id = candidate.candidate_id
ORDER BY
candidate_joborder.date_modified DESC
LIMIT 1
) AS lastStatus

我的问题是“我可以采取哪些措施加快查询速度”?数据库上只有8000行,并且有大量的服务器资源。这些表是MyISAM,我已经尝试添加索引,你可以看到一些在解释中使用但是我不认为索引真的会有多大帮助,因为它看起来是什么使这个慢是concat,filesort,临时表(与没有索引)可能是三连接。

这是我的第一篇帖子,请原谅格式化。我会在发布后尝试编辑它,看看它看起来如何。

谢谢

3 个答案:

答案 0 :(得分:0)

您也可以索引临时表,它可以提高性能,并尽可能避免文件排序。另一个可以帮助您的资源是procedure_analyse选项。它将帮助您创建适当的变量类型。

在此处查找更多信息: https://dev.mysql.com/doc/refman/5.7/en/procedure-analyse.html

答案 1 :(得分:0)

感谢您提供的信息,我安装了mariadb 10.1,现在一切都很好。它是在5.5 centos7

答案 2 :(得分:0)

SELECT  CONCAT( '<a href="index.php?m=joborders&amp;a=show&amp;jobOrderID=',
                j.joborder_id, '" title="', j.title, 
                ' (', co.name, ')">',
                cjs.short_description, '</a>' 
              )
    FROM  candidate_joborder AS cj
    LEFT JOIN  candidate_joborder_status AS cjs
          ON cjs.candidate_joborder_status_id = cj.status
    LEFT JOIN  joborder AS j
          ON j.joborder_id = cj.joborder_id
    LEFT JOIN  company AS co
          ON j.company_id = co.company_id
    WHERE  cj.candidate_id = c.candidate_id
    ORDER BY  cj.date_modified DESC
    LIMIT  1 

cj需要INDEX(candidate_id, date_modified)

    WHERE  candidate.site_id = 1
    GROUP BY  candidate.candidate_id
    ORDER BY  dateModifiedSort DESC

candidate需要INDEX(site_id, candidate_id)

注意:INDEX(a,b) INDEX(a), INDEX(b)相同。