对于报告输出,我曾经DROP并重新创建表'mis.pr_approval_time'。但现在我只是截止它。
用数据填充上面的表后,我运行了一个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表中只有~3,400行,pr_approval_time中只有29,000行。我在具有15 GB以上RAM的Amazon AWS实例上运行它。
现在,如果我只是右键单击pr_approval_time表并选择ALTER TABLE选项,并且只是关闭而不做任何事情,那么上述查询将在几秒钟内运行。
我想当我触发ALTER TABLE选项并且Workbench填充表字段时,它可能会以某种方式改进其执行计划,但我不确定为什么。有没有人遇到类似的事情?如何在不右键单击表格并选择“ALTER TABLE”
的情况下触发更好的执行计划检查修改
值得一提的是,我的组织也使用DOMO。最初,我把这个设置作为DOMO上的MySQL数据流,但是查询在大多数时候都没有完成,但我观察到它有时会完成。
这就是我将此查询移回AWS MySQL RDS的原因。所以问题不仅出现在我们自己的MySQL RDS上,而且可能也出现在DOMO上
答案 0 :(得分:0)
假设您在连接所涉及的列上有适当的索引 您可以尝试使用子查询分组重构您的查询并加入国家/地区
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
答案 1 :(得分:0)
我怀疑这是因为相关子查询很慢(子查询依赖于父表的行值,这意味着它必须为每一行执行)。我尝试稍微重新编写pr_approval_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