MySQL предпочитает выполнять запросы или нет по желанию

0

Для вывода отчета я использовал 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 есть только ~ 3400 строк и 29 000 строк в pr_approval_time. Я запускаю это на экземпляре Amazon AWS с 15+ GB RAM.

Теперь, если я просто щелкнуть правой кнопкой мыши по таблице pr_approval_time и выбрать параметр ALTER TABLE и просто закрыть, ничего не делая, то указанные выше запросы выполняются в течение нескольких секунд.

Я думаю, когда я запускаю параметр ALTER TABLE, а Workbench заполняет поля таблицы, это, вероятно, как-то улучшает его план выполнения, но я не уверен, почему. Кто-нибудь сталкивался с чем-то похожим на это? Как я могу инициировать лучшую проверку плана выполнения без щелчка правой кнопкой мыши по таблице и выбора "ALTER TABLE"

РЕДАКТИРОВАТЬ

Можно отметить, что моя организация также использует DOMO. Первоначально у меня была эта настройка как MySQL Dataflow на DOMO, но запрос не завершился в большинстве случаев, но я наблюдал, как это заканчивалось время от времени.

Именно по этой причине я переместил этот запрос обратно в наш AWS MySQL RDS. Таким образом, проблема не только наблюдается на нашем собственном MySQL RDS, но, вероятно, также на DOMO

  • 0
    Индексировали ли вы столбцы, участвующие в предложении WHERE? Это был бы самый простой шаг настройки производительности.
  • 0
    @Littlefoot yes, в обеих таблицах созданы индексные столбцы, которые отображаются в плане запросов (объяснение). Когда я вижу его там, он появляется с зелеными полями, но запрос просто не завершается. Кроме того, как я уже упоминал выше, 30000 строк - это почти что угодно, даже без индексных столбцов.
Теги:
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
    Мне пришлось немного изменить ваш запрос, но он работает нормально. Не уверен, почему, хотя.
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
  • 0
    Не уверен, понимаете ли вы, что я пытался сделать, но нет точного соответствия между временем утверждения и временем создания опроса. Поэтому я использую подзапрос, чтобы получить время утверждения, наиболее близкое к созданию опроса. Сначала происходит утверждение, а затем создание опроса.
  • 0
    если вы показываете правильную выборку данных и ожидаемый результат .. легче понять, что вы пытаетесь сделать ..

Ещё вопросы

Сообщество Overcoder
Наверх
Меню