Ich habe ein Ereignis, das einige Daten erzeugt, die accumulators
in was ich ein transaction
nennen. Es stellte sich heraus, dass es viel schneller lief und den Akku von Grund auf neu erzeugte, als zu versuchen, sie mit bestehenden zu vergleichen. Deshalb habe ich ihnen eine transaction_id
gegeben, sie erstellen und dann in einer Abfrage die vorherigen Transaktionen löschen.Mysql schnell einfügen, langsam löschen, falscher Index
Erstellung von ca. 2 Millionen Zeilen in der Tabelle benötigen ungefähr 40 Sekunden, aber das Löschen dauert derzeit ungefähr 20-30 Minuten mit der folgenden Abfrage.
DELETE
FROM accumulator
WHERE id_acca_set = @set_id
AND (transaction_id != @transaction_id or transaction_id is null);
Mit Blick auf den innodb-Status sehe ich Folgendes, wenn die Abfrage ausgeführt wird. Soweit ich herausfinden kann, scheint es zu diesem Zeitpunkt keine widersprüchliche Sperre zu geben.
---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
Die Tabelle accumulator
ist wie folgt definiert. Ich habe festgestellt, dass es nicht IDX_accumulator5
sondern IDX_accumulator3
verwendet, die nicht die transaction_id
stattdessen enthält.
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;
Ich bin mit MySQL 5.7.13 auf CentOS 7. Ich habe keinen Swap-Speicher verwenden und haben über 10 GB freien Speicher verbleiben, werden 6GB im InnoDB Zwischenspeicher zugeordnet. InnoDB Einstellungen in my.cnf
sind:
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
Sie sagen, dass Sie löschen müssen 2.000.000 Zeilen ..? – scaisEdge
Titel liest sich wie ein Gedicht: D –