提问人:Kushal Singh 提问时间:8/28/2023 最后编辑:Kushal Singh 更新时间:10/17/2023 访问量:213
从 MySql 5.7 升级到 8 后,Redmine 查询非常慢
Redmine query is very slow after upgrading from MySql 5.7 to 8
问:
最近,我们将 Redmine 的 MySql 版本从 5.7 升级到 8.0.32。升级后,MyPage 查询需要很长时间才能执行(大约 1 分钟)。以前在 5.7 版中,它曾经在几秒钟内执行。
在最初的研究中,MySql 8 使用派生的查询优化概念,因此在 5.7 和 8 中解释查询的逻辑是不同的。
Redmine 版本:4.1.1.stable(在最新的 redmine 版本 5.0.5 上尝试过,但遇到了同样的问题。此外,所有适当的索引也已完成)
MyPage查询:
SELECT
issues.id AS t0_r0,
issues.tracker_id AS t0_r1,
issues.project_id AS t0_r2,
issues.subject AS t0_r3,
issues.description AS t0_r4,
issues.due_date AS t0_r5,
issues.category_id AS t0_r6,
issues.status_id AS t0_r7,
issues.assigned_to_id AS t0_r8,
issues.priority_id AS t0_r9,
issues.fixed_version_id AS t0_r10,
issues.author_id AS t0_r11,
issues.lock_version AS t0_r12,
issues.created_on AS t0_r13,
issues.updated_on AS t0_r14,
issues.start_date AS t0_r15,
issues.done_ratio AS t0_r16,
issues.estimated_hours AS t0_r17,
issues.parent_id AS t0_r18,
issues.root_id AS t0_r19,
issues.lft AS t0_r20,
issues.rgt AS t0_r21,
issues.is_private AS t0_r22,
issues.position AS t0_r23,
issues.remaining_hours AS t0_r24,
issues.story_points AS t0_r25,
issues.closed_on AS t0_r26,
issue_statuses.id AS t1_r0,
issue_statuses.name AS t1_r1,
issue_statuses.is_closed AS t1_r2,
issue_statuses.position AS t1_r3,
issue_statuses.default_done_ratio AS t1_r4,
projects.id AS t2_r0,
projects.name AS t2_r1,
projects.description AS t2_r2,
projects.homepage AS t2_r3,
projects.is_public AS t2_r4,
projects.parent_id AS t2_r5,
projects.created_on AS t2_r6,
projects.updated_on AS t2_r7,
projects.identifier AS t2_r8,
projects.status AS t2_r9,
projects.lft AS t2_r10,
projects.rgt AS t2_r11,
projects.inherit_members AS t2_r12,
projects.default_version_id AS t2_r13,
projects.default_assigned_to_id AS t2_r14
FROM
issues
INNER JOIN projects ON projects.id = issues.project_id
INNER JOIN issue_statuses ON issue_statuses.id = issues.status_id
LEFT OUTER JOIN enumerations ON enumerations.id = issues.priority_id
WHERE
(projects.status <> 9
AND EXISTS (
SELECT 1
FROM enabled_modules em
WHERE em.project_id = projects.id AND em.name='issue_tracking'
))
AND (
issues.status_id IN (SELECT id FROM issue_statuses WHERE is_closed=FALSE)
AND issues.assigned_to_id IN ('1051', '2643')
AND projects.status IN ('1')
)
ORDER BY
enumerations.position DESC,
issues.updated_on DESC,
issues.id DESC
LIMIT 10;
MySQL 8.0.32 解释
编号 | select_type | 桌子 | 分区 | 类型 | possible_keys | 我? | key_len | 裁判 | 行 | 过滤 | 额外 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 简单 | issue_statuses | 都 | 主要 | 19 | 100 | 使用临时;使用文件排序 | ||||
1 | 简单 | issue_statuses | eq_ref | 主要,index_issue_statuses_on_is_closed | 主要 | 4 | deermine.issue_statuses.id | 1 | 89.47 | 使用where | |
1 | 简单 | 都 | 100 | 在哪里使用;使用连接缓冲区(哈希连接) | |||||||
1 | 简单 | 项目 | eq_ref | 主要 | 主要 | 4 | .project_id | 1 | 9 | 使用where | |
1 | 简单 | 问题 | 裁判 | issues_project_id,index_issues_on_status_id,index_issues_on_assigned_to_id | issues_project_id | 4 | .project_id | 1917 | 0.03 | 使用where | |
1 | 简单 | 枚举 | eq_ref | 主要,index_enumerations_on_id_and_type | 主要 | 4 | deermine.issues.priority_id | 1 | 100 | ||
2 | 物化 | 他们 | 都 | enabled_modules_project_id | 3545 | 10 | 使用where |
MySQL 5.7 解释
编号 | select_type | 桌子 | 分区 | 类型 | possible_keys | 我? | key_len | 裁判 | 行 | 过滤 | 额外 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 主要 | 问题 | 范围 | issues_project_id,index_issues_on_status_id,index_issues_on_assigned_to_id | index_issues_on_assigned_to_id | 5 | 2560 | 100 | 使用索引条件;使用临时;使用文件排序 | ||
1 | 主要 | issue_statuses | eq_ref | 主要,index_issue_statuses_on_is_closed | 主要 | 4 | deermine.issues.status_id | 1 | 89.47 | 使用where | |
1 | 主要 | issue_statuses | eq_ref | 主要 | 主要 | 4 | deermine.issues.status_id | 1 | 100 | ||
1 | 主要 | 枚举 | eq_ref | 主要,index_enumerations_on_id_and_type | 主要 | 4 | deermine.issues.priority_id | 1 | 100 | ||
1 | 主要 | 项目 | eq_ref | 主要 | 主要 | 4 | deermine.issues.project_id | 1 | 9 | 使用where | |
2 | 依赖子查询 | 他们 | 裁判 | enabled_modules_project_id | enabled_modules_project_id | 5 | deermine.projects.id | 5 | 10 | 使用where |
如您所见,在 5.7 中,所有行都在单个查询中被拉取,而在 8.0.32 中,所有行都是在多个查询中被拉取的。
有什么办法解决这个问题吗?
答:
3赞
Kushal Singh
8/31/2023
#1
我们通过关闭 MySQL 8 optimizer_switch中的“具体化”开关来解决此问题。关闭具体化开关后,SQL 不会为存在条件的位置创建临时表,从而加快查询的执行速度。
执行时间从 1+ 分钟下降到不到一毫秒。
评论
0赞
ron
10/17/2023
这解决了我们的 CPU 一直达到 100%,但我们仍然看到很多缓慢的查询,我们在 explain 命令中注意到,它没有使用 PRIMARY/SUBQUERY,而是在选择类型列中使用 SIMPLE,您是否对 mysql 优化器进行了任何其他更改?
1赞
Arie S.
10/17/2023
#2
我们遇到了同样的问题,我们在optimizer_switch进行了更改,但它只解决了部分问题。materialization=off
之后,我们在 MySQL 8 中设置并得到了与 MySQL 5.7 中完全相同的执行计划。materialization=on,semijoin=off
评论
EXPLAIN {query}