2016-08-18 6 views
-1

У меня есть событие, которое генерирует некоторые данные, представляющие accumulators в том, что я называю transaction. Было доказано, что он намного быстрее генерирует аккумулятор с нуля, чем пытается сопоставить их с существующими. Поэтому я дал им transaction_id, создаю их, а затем в одном запросе удаляю предыдущие транзакции.Mysql быстрая вставка, медленное удаление, неправильный указатель

Создание ок. 2 миллиона строк в таблице требуется около 40 секунд, однако удаление в настоящее время занимает около 20-30 минут, используя запрос ниже.

DELETE 
    FROM accumulator 
WHERE id_acca_set = @set_id 
    AND (transaction_id != @transaction_id or transaction_id is null); 

Глядя на статус innodb, я вижу следующее при выполнении запроса. Насколько я могу понять, на данном этапе, похоже, нет противоречивого замка.

---TRANSACTION 11535589892, ACTIVE 259 sec updating or deleting, thread declared inside InnoDB 4657 
mysql tables in use 1, locked 1 
29009 lock struct(s), heap size 3776720, 1195753 row lock(s), undo log entries 1195753 
MySQL thread id 108262, OS thread handle 131874376460032, query id 9689717638 event_scheduler updating 

Таблица accumulator приведена ниже. Я заметил, что он не использует IDX_accumulator5, но IDX_accumulator3, который вместо этого содержит transaction_id.

CREATE TABLE acca.accumulator (
id bigint(20) NOT NULL AUTO_INCREMENT, 
id_acca_set int(1) NOT NULL DEFAULT 0, 
id_event bigint(20) NOT NULL DEFAULT 0, 
id_back_outcome bigint(20) NOT NULL DEFAULT 0, 
id_lay_outcome bigint(20) NOT NULL DEFAULT 0, 
acca_id varchar(255) DEFAULT NULL, 
prev_acca_id varchar(255) DEFAULT NULL, 
leg_number int(11) NOT NULL, 
score double DEFAULT NULL, 
transaction_id varchar(255) DEFAULT NULL, 
PRIMARY KEY (id), 
INDEX IDX_accumulator (id_acca_set, acca_id, transaction_id), 
INDEX IDX_accumulator2 (id_acca_set, leg_number, acca_id, transaction_id), 
INDEX IDX_accumulator3 (id_acca_set, id_event, id_back_outcome, id_lay_outcome, leg_number), 
INDEX IDX_accumulator4 (id_acca_set, prev_acca_id, id_event), 
INDEX IDX_accumulator5 (id_acca_set, transaction_id), 
INDEX IDX_accumulator6 (transaction_id, id_acca_set, leg_number, score) 
) 
ENGINE = INNODB 
AUTO_INCREMENT = 242051170 
AVG_ROW_LENGTH = 282 
CHARACTER SET utf8 
COLLATE utf8_general_ci 
ROW_FORMAT = DYNAMIC; 

Я бег MySQL 5.7.13 на CentOS 7. Я не использовать память подкачки и иметь о 10GB свободной памяти, 6 выделяются на InnoDB буфер. Настройки InnoDB в my.cnf являются:

innodb_buffer_pool_size = 6G 
innodb_buffer_pool_instances = 6 
innodb_commit_concurrency = 4 
innodb_flush_method = O_DIRECT 
innodb_thread_concurrency = 8 
innodb_thread_sleep_delay = 100 
innodb_flush_log_at_trx_commit = 1 
innodb_flush_log_at_timeout = 10 
+0

Вы говорите, что вам нужно удалить 2.000.000 строк.? – scaisEdge

+0

Название читается как стихотворение: D –

ответ

1

Я не в курсе каких-либо СУБД, которые будут использовать индекс для решения отрицанием предиката (TRANSACTION_ID = @transaction_id!).

Я не понимаю, почему вы добавляете новые записи , затем удаляя старые. Если вы сделаете это наоборот (обрезайте таблицу), тогда потребуется немного времени. Если вы хотите, чтобы у вас были данные, чтобы вернуться, альтернативным подходом было бы переименование существующей таблицы, а затем создание новой (с исходным именем) для хранения новых данных.

+0

Я считал обрезание таблицы и выполнение именно того, что вы предлагаете, но у меня есть несколько наборов acca и не могу просто полностью переименовать таблицу. Также, как только я сгенерировал новый набор, мне нужно переключить другой расчет, чтобы использовать новую транзакцию, которая по разным причинам я не могу сделать в одной транзакции. – Hans

+1

Предполагая, что вы не хотите создавать представление о соединении старых таблиц данных (что имеет смысл при выполнении производительности), вы можете использовать атрибут состояния (который может быть отключен от триггера). – symcbean

+0

Я закончил с другой таблицей где я регистрирую все транзакции и их статус. Теперь я использую это для удаления истекших транзакций и может точно определить совпадающие записи с помощью '= @ transaction_id', а не отрицания. – Hans