2016-11-12 3 views
0

Я пытаюсь запустить многосетевое обновление в MYSQL (Amazon RDS), и это очень медленно.MYSQL Multi-Table Update Extremely Slow

Что я пытаюсь сделать?

Удалите все повторяющиеся строки на основе 1-часового периода времени.

Ниже я создал временную таблицу для идентификации повторяющихся строк в таблице. Этот запрос выполняется через 2 секунды.

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ; 

CREATE TEMPORARY TABLE tmpIds (id int primary key); 
INSERT into tmpIds 
SELECT distinct 
    d.id 
FROM api d INNER JOIN api orig 
    on d.domain_id = orig.domain_id and d.user_id = orig.user_id 
WHERE 
    orig.created_at < d.created_at 
    AND d.created_at <= DATE_ADD(orig.created_at, Interval 1 hour) 
    AND d.type = 'api/check-end' 
    AND d.created_at >= '2016-08-01'; 

SET TRANSACTION ISOLATION LEVEL READ COMMITTED ; 

Проблема заключается в том, что запрос UPDATE длится долго, чтобы работать на производственном сервере. Он также блокирует таблицу api.

SET @TRIGGER_DISABLED = 1; 

UPDATE 
    api 
SET 
    deleted_at = now() 
WHERE type = 'api/check-end' AND created_at >= '2016-08-01' 
    AND id IN (SELECT id FROM tmpIds); 

SET @TRIGGER_DISABLED = 0; 

Я также попробовал эту версию:

SET @TRIGGER_DISABLED = 1; 

UPDATE 
    api a, 
    tmpIds ti 
SET 
    a.deleted_at = now() 
WHERE 
    type = 'api/check-end' AND created_at >= '2016-08-01' AND a.domain_id < 10 AND a.id = ti.id; 

SET @TRIGGER_DISABLED = 0; 

СТАТИСТИКУ

  • Темп Таблица: 32000 строк
  • апи таблица: всего - 250000 строк, после где положение (тип , created_at) 200 000 строк.
  • В таблице api есть дорогостоящие триггеры, поэтому я повернул их .
  • Пример прогона 1000 обновлений 6 минут.
  • Существует индекс по апи первичного ключа таблицы
+0

Показать объяснение. Одна вещь, которую вы могли бы сделать, это заменить подзапрос JOIN, но проблема может заключаться в том, что временная таблица не может быть проиндексирована, вам может быть лучше с реальной таблицей, которую вы можете усекать по мере необходимости. – Mihai

ответ

0

Проблема заключалась в следующем заявлении:

SET @TRIGGER_DISABLED = 1; 

не был отключение триггеров. Мне пришлось удалить триггер UPDATE в таблице api, а UPDATE - через 1,3 секунды.

Любая помощь по наилучшему способу отключения триггеров во время выполнения запроса?

+0

Если вам не нужен триггер, возможно, соедините все это вместе и используйте планировщик событий, чтобы создать событие, которое будет делать то, что должен был запускать в определенные промежутки времени? Похоже, что там есть какая-то тяжелая обработка, если вам не нужен триггер при обновлении, может быть, заменить его? –

+0

Спасибо за ответ, мы переместим все триггеры на сохраненные procs. – DropAcid