关于update语句返回的影响行数

今天很忙,本来想存成草稿有空在编辑的。结果一不小心发布了,所以只能先写完了。

先描述下背景,一个提问的问题

以前我认为,只要是update的where条件可以找到数据的,那么返回的影响行数必然是大于0的。


写了一个SQL: UPDATE tss_view_template SET name='默认风格' where id=1; 结果返回影响行数是0,但是SQL变成这样: UPDATE tss_view_template SET name='默认风格',gmt_create=now() where id=1; 结果返回影响行数是1 难道说这条update的执行之前,会先比对你要更新的字段,如果是一样的,就不算是更新 还是说这个是MySQL的特性


把这个问题简单的归纳下就是,updae语句如果不实际改变数据,那么会不会在底层做操作?

于是在本地做了一下测试


mysql> update test set a=1 where b=2;
Query OK, 0 rows affected
Rows matched: 1  Changed: 0  Warnings: 0

mysql> select row_count();
+-------------+
| row_count() |
+-------------+
|           0 |
+-------------+
1 row in set

mysql> update test set a=2 where b=2;
Query OK, 1 row affected
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select row_count();
+-------------+
| row_count() |
+-------------+
|           1 |
+-------------+
1 row in set

mysql> select version();
+-----------+
| version() |
+-----------+
| 5.5.15    |
+-----------+
1 row in set
我的测试环境是mysql5.5.15,其中row mathc和row change却是和问题中的描述一样。我们主要关注一下change这个数列


另外我再实验中使用了select row_count这个函数,可以看到这个值和change是一致的。

关于row_count这个函数,我们可以参考一下mysql的文档 ,mysql的官方文档上是这么写的“For UPDATE statements, the affected-rows value by default is the number of rows actually changed. If you specify the CLIENT_FOUND_ROWS flag to mysql_real_connect() when connecting to mysqld, the affected-rows value is the number of rows “found”; that is, matched by the WHERE clause.” 也就是说是默认情况下是actually影响的值,但是在mysql启动的时候改变下CLIENT_FOUND_ROWS这个值的话就是“发现的值”而不是“改变的值”。下面是参考文档的原文

http://dev.mysql.com/doc/refman/5.5/en//information-functions.html#function_row-count

另外关于row_count这个问题 有人在stackoverflow中提过相似的问题。意思是这个好像和mysql的版本有关,见下面的连接

http://stackoverflow.com/questions/12673925/row-count-returns-0-after-insert-or-update

但是我特意在5.1上做了这个实验,并没有复现这个问题。下面是我在本地的实验截图

mysql究竟是怎么做的呢?


有两个值。 Rows matched和Changed 前者表示匹配的行数,后者表示改变的行数。 如果update语句没有对数据做出修改,则changed为0,如果有一行匹配的记录的话,Rows matched为1 
在进入Innodb层时,会判断是否做出修改,ha_innobase::update_row->calc_row_difference 不过从代码的逻辑来看,即使需要更新的字段数为0,还是会跑到更新记录的逻辑,只是没有修改任何数据而已 
例如 mysql> create table x1 (a int, b int); Query OK, 0 rows affected (0.00 sec) 
mysql> insert into x1 values (1,2),(2,3); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 
mysql> update x1 set a=1 where b =2; Query OK, 0 rows affected (0.00 sec) Rows matched: 1 Changed: 0 Warnings: 0 
mysql> update x1 set a=12 where b =2; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0

可以参考这个mysql的文档

http://blogs.innodb.com/wp/2010/09/mysql-5-5-innodb-change-buffering/

 mysql是这样的,那么oracle对于update相同的行时又是怎么做的呢?


这里我就不做实验了,参考一个网上的博客,得到的结论就是oracle在处理相同行的时候会是会做更新操作的。




总结一下,msyql在update相同的行的时候是不会做change操作的,而oracle是会记录这个行的。



转载于:https://my.oschina.net/zimingforever/blog/83810

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值