MySQL选择是否突然执行查询

时间:2018-03-06 19:44:38

标签: mysql sql mysql-workbench sql-execution-plan

对于报告输出,我曾经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上

2 个答案:

答案 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