我有一个事件会在我称之为accumulators
的内容中生成一些代表transaction
的数据。事实证明,从头开始生成累加器的速度比尝试将它们与现有累加器相匹配要快得多。因此,我给了他们一个transaction_id
,创建它们,然后在一个查询中删除之前的交易。
创建约。表中的200万行需要大约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;
我在CentOS 7上运行MySQL 5.7.13。我没有使用交换内存,剩余大约10GB可用内存,6GB分配给INNODB缓冲区。 my.cnf
中的InnoDB设置为:
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 :(得分:1)
我不知道任何使用索引来解析否定谓词的DBMS(transaction_id!= @transaction_id)。
我不明白为什么要添加新记录然后删除旧记录。如果你反过来这样做(截断表格)那么它将花费很少的时间。如果您想确保有数据可供使用,那么另一种方法是重命名现有表,然后创建一个新表(使用原始名称)来保存新数据。