Executed update queries always return the number of rows matched by the query, including rows that didn't have to be updated because their values wouldn't have changed.

In Drupal 7, this used to be inconsistent, depending on database engine and version:

MySQL / InnoDB: changed rows only
(except on MySQL 5.1.0 - 5.1.24: all rows matched by the query)
MySQL / MyISAM: changed rows only
PostgreSQL: all rows matched by the query
SQLite: changed rows only

Since PHP 5.3 (which we already require), the MySQL connection can be switched to use this behavior by using the PDO::MYSQL_ATTR_FOUND_ROWS flag when opening the database connection.

Note that this relates to all update queries whether executed from a Database::getConnection()->update() object or its procedural wrapper db_update().
However, in most cases where you want to know the number of affected rows, a merge query might be the even better solution, see Database::getConnection()->merge() or its procedural wrapper db_merge().

Introduced in branch: 
1.0.x
Introduced in version: 
1.0.0
Impacts: 
Module developers