首页 > 解决方案 > 没有净效应的事务是否会触及磁盘上的数据库?

问题描述

我有一种情况需要更新一些表行,将未出现在外部数据源中的行标记为禁用(即 update active=0)。直截了当的解决方案是BEGIN一个事务,UPDATE每一行到active=0,然后扫描远程数据,UPDATE为每个应该active=1放回它的条目做一个。我有大约 1k 行,所以这应该是一个相对快速的操作,即使有很多低效的查询解析。

但是,这些数据通常根本不会改变。因此,在大多数情况下,交易的净影响将是零变化。如果数据库引擎将解决整个问题,检测到没有任何变化,并且结果没有任何变化,那将是理想的。但是,如果它每次都要经历并实际更新每一行,我宁愿找到另一个解决方案。

标签: mysqlmariadb

解决方案


这是一个演示。我创建了一个表格,其中只有一个简单的整数。

mysql> create table t ( i int );
mysql> insert into t set i = 42;

我检查当前的日志写入次数。

mysql> show status like 'innodb_log_write_requests';
+---------------------------+---------+
| Variable_name             | Value   |
+---------------------------+---------+
| Innodb_log_write_requests | 5432152 |
+---------------------------+---------+

然后使用 UPDATE 更改行中的值并确认它导致了日志写入:

mysql> update t set i = 43;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> show status like 'innodb_log_write_requests';
+---------------------------+---------+
| Variable_name             | Value   |
+---------------------------+---------+
| Innodb_log_write_requests | 5432153 |
+---------------------------+---------+

接下来,进行没有净效果的更新。

mysql> update t set i = 43;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0

注意Changed: 0

看日志写的,也是不变的:

mysql> show status like 'innodb_log_write_requests';
+---------------------------+---------+
| Variable_name             | Value   |
+---------------------------+---------+
| Innodb_log_write_requests | 5432153 |
+---------------------------+---------+

推荐阅读