MySQL 随意选择是否执行查询
MySQL chooses to execute queries, or not, at whim
对于报告输出,我曾经删除并重新创建 table 'mis.pr_approval_time'。但现在我只是截断它。
用数据填充上面的 table 之后,我 运行 一个 UPDATE 语句,但我已经把它写成下面的 SELECT...
SELECT t.account_id FROM mis.hj_approval_survey h INNER JOIN mis.pr_approval_time t ON h.country = t.country AND t.scheduled_at =
(
SELECT MAX(scheduled_at) FROM mis.pr_approval_time
WHERE country = h.country
AND scheduled_at <= h.created_at
AND TIME_TO_SEC(TIMEDIFF(h.created_at, scheduled_at)) < 91
);
当我运行上面的语句甚至只是...
SELECT t.account_id FROM mis.hj_approval_survey h INNER JOIN mis.pr_approval_time t ON h.country = t.country AND t.scheduled_at =
(
SELECT MAX(scheduled_at) FROM mis.pr_approval_time
WHERE country = h.country
);
...它 运行 永远不会结束。 hj_approval_survey table 中只有约 3,400 行,pr_approval_time 中只有 29,000 行。我 运行 在具有 15+ GB RAM 的 Amazon AWS 实例上执行此操作。
现在,如果我简单地右键单击 pr_approval_time table 并选择 ALTER TABLE 选项,然后不做任何事情就关闭,那么上面的查询 运行秒。
我想当我触发 ALTER TABLE 选项并且 Workbench 填充 table 字段时,它可能以某种方式改进了它的执行计划,但我不确定为什么。有没有人遇到过类似的事情?如何在不右键单击 table 并选择 'ALTER TABLE'
的情况下触发更好的执行计划检查
编辑
值得一提的是,我的组织也使用 DOMO。最初,我将此设置作为 DOMO 上的 MySQL 数据流,但查询在大多数情况下都无法完成,但我观察到它有时会完成。
这就是我将此查询移回我们的 AWS MySQL RDS 的原因。所以这个问题不仅在我们自己的 MySQL RDS 上观察到了,而且可能在 DOMO
上也观察到了
假设您在连接涉及的列上有适当的索引
您可以尝试使用按子查询分组并加入国家
来重构您的查询
SELECT t.account_id
FROM mis.hj_approval_survey h
INNER JOIN mis.pr_approval_time t ON h.country = t.country
INNER JOIN (
SELECT country, MAX(scheduled_at) max_sched
FROM mis.pr_approval_time
group by country
) z on z.contry = t.country and t.scheduled_at = z.max_sched
我怀疑这很慢,因为相关的子查询(子查询取决于来自父 table 的行值,这意味着它必须对每一行执行)。我会尝试稍微修改 pr_approval_time table 所以它是 point-in-time 然后你可以使用 JOIN 来选择正确的行而不用做相关的子查询。类似于:
SELECT
hj_approval_survey.country
, hj_approval_survey.created_at
, pr_approval_time.account_id
FROM
@hj_approval_survey AS hj_approval_survey
JOIN (
SELECT
current_row.country
, current_row.scheduled_at AS scheduled_at_start
, COALESCE( MIN( next_row.scheduled_at ), GETDATE() ) AS scheduled_at_end
FROM
@pr_approval_time AS current_row
LEFT OUTER JOIN
@pr_approval_time AS next_row ON (
next_row.country = current_row.country
AND next_row.scheduled_at > current_row.scheduled_at
)
GROUP BY
current_row.country
, current_row.scheduled_at
) AS pr_approval_pit ON (
pr_approval_pit.country = hj_approval_survey.country
AND ( hj_approval_survey.created_at >= pr_approval_pit.scheduled_at_start
AND hj_approval_survey.created_at < pr_approval_pit.scheduled_at_end
)
)
JOIN @pr_approval_time AS pr_approval_time ON (
pr_approval_time.country = pr_approval_pit.country
AND pr_approval_time.scheduled_at = pr_approval_pit.scheduled_at_start
)
WHERE
TIME_TO_SEC( TIMEDIFF( hj_approval_survey.created_at, pr_approval_time.scheduled_at ) ) < 91
对于报告输出,我曾经删除并重新创建 table 'mis.pr_approval_time'。但现在我只是截断它。
用数据填充上面的 table 之后,我 运行 一个 UPDATE 语句,但我已经把它写成下面的 SELECT...
SELECT t.account_id FROM mis.hj_approval_survey h INNER JOIN mis.pr_approval_time t ON h.country = t.country AND t.scheduled_at =
(
SELECT MAX(scheduled_at) FROM mis.pr_approval_time
WHERE country = h.country
AND scheduled_at <= h.created_at
AND TIME_TO_SEC(TIMEDIFF(h.created_at, scheduled_at)) < 91
);
当我运行上面的语句甚至只是...
SELECT t.account_id FROM mis.hj_approval_survey h INNER JOIN mis.pr_approval_time t ON h.country = t.country AND t.scheduled_at =
(
SELECT MAX(scheduled_at) FROM mis.pr_approval_time
WHERE country = h.country
);
...它 运行 永远不会结束。 hj_approval_survey table 中只有约 3,400 行,pr_approval_time 中只有 29,000 行。我 运行 在具有 15+ GB RAM 的 Amazon AWS 实例上执行此操作。
现在,如果我简单地右键单击 pr_approval_time table 并选择 ALTER TABLE 选项,然后不做任何事情就关闭,那么上面的查询 运行秒。
我想当我触发 ALTER TABLE 选项并且 Workbench 填充 table 字段时,它可能以某种方式改进了它的执行计划,但我不确定为什么。有没有人遇到过类似的事情?如何在不右键单击 table 并选择 'ALTER TABLE'
的情况下触发更好的执行计划检查编辑
值得一提的是,我的组织也使用 DOMO。最初,我将此设置作为 DOMO 上的 MySQL 数据流,但查询在大多数情况下都无法完成,但我观察到它有时会完成。
这就是我将此查询移回我们的 AWS MySQL RDS 的原因。所以这个问题不仅在我们自己的 MySQL RDS 上观察到了,而且可能在 DOMO
上也观察到了假设您在连接涉及的列上有适当的索引 您可以尝试使用按子查询分组并加入国家
来重构您的查询 SELECT t.account_id
FROM mis.hj_approval_survey h
INNER JOIN mis.pr_approval_time t ON h.country = t.country
INNER JOIN (
SELECT country, MAX(scheduled_at) max_sched
FROM mis.pr_approval_time
group by country
) z on z.contry = t.country and t.scheduled_at = z.max_sched
我怀疑这很慢,因为相关的子查询(子查询取决于来自父 table 的行值,这意味着它必须对每一行执行)。我会尝试稍微修改 pr_approval_time table 所以它是 point-in-time 然后你可以使用 JOIN 来选择正确的行而不用做相关的子查询。类似于:
SELECT
hj_approval_survey.country
, hj_approval_survey.created_at
, pr_approval_time.account_id
FROM
@hj_approval_survey AS hj_approval_survey
JOIN (
SELECT
current_row.country
, current_row.scheduled_at AS scheduled_at_start
, COALESCE( MIN( next_row.scheduled_at ), GETDATE() ) AS scheduled_at_end
FROM
@pr_approval_time AS current_row
LEFT OUTER JOIN
@pr_approval_time AS next_row ON (
next_row.country = current_row.country
AND next_row.scheduled_at > current_row.scheduled_at
)
GROUP BY
current_row.country
, current_row.scheduled_at
) AS pr_approval_pit ON (
pr_approval_pit.country = hj_approval_survey.country
AND ( hj_approval_survey.created_at >= pr_approval_pit.scheduled_at_start
AND hj_approval_survey.created_at < pr_approval_pit.scheduled_at_end
)
)
JOIN @pr_approval_time AS pr_approval_time ON (
pr_approval_time.country = pr_approval_pit.country
AND pr_approval_time.scheduled_at = pr_approval_pit.scheduled_at_start
)
WHERE
TIME_TO_SEC( TIMEDIFF( hj_approval_survey.created_at, pr_approval_time.scheduled_at ) ) < 91