MySQL随心所欲地选择是否执行查询

问题描述 投票:0回答:2

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

mysql sql mysql-workbench sql-execution-plan
2个回答
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

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
© www.soinside.com 2019 - 2024. All rights reserved.