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

标签 mysql performance join concatenation 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、文件排序、临时表(与没有索引)和可能的三重连接。

这是我的第一篇文章,所以请原谅格式。我会在发布后尝试编辑它,看看它的外观。

谢谢

最佳答案

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

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

关于mysql - 使用 concat 和 filesort 时 mysql 查询速度变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48770233/

相关文章:

使用 Join 的 MySQL 数据透视表

php - 强制 CodeIgniter 显示 404 页面而不是任何其他错误,如 1064

Mysql性能调优问题

SQL Server 2005 - 多处理器使用

c++ - 使用黑名单边缘提升过滤图

Java:如果加入线程不起作用:中断还是继续?

Mysql程序执行时出错

mysql - 有没有办法根据 where 条件下的数据值从 mysql 中的单个选择查询中获取多个输出文件?

sql - 加快数据在两个日期之间的 PostgreSQL 查询

mysql - 仅根据第一组值连接两个表