I'd definitely go for field_attach_update
.
The idea is simple. Just load the node and save it using field_attach_update.
Ex:
$node = node_load($nid);
$node->field_name[LANGUAGE_NONE][0]['value'] = 'New value';
field_attach_presave('node', $node);
field_attach_update('node', $node);
// Clear the static loading cache.
entity_get_controller('node')->resetCache(array($node->nid));
This will not changed any timestamp or any other hook that node_save usually invokes. Loading the node will also invoke some hooks so probably it's not that efficient.
If you have the nid and if the node structure is dead simple, you can do it like this as well:
$node = new stdClass();
$node->nid = $nid; // Enter the nid taken. Make sure it exists.
$node->type = 'article';
$node->field_name[LANGUAGE_NONE][0]['value'] = 'New value';
field_attach_presave('node', $node);
field_attach_update('node', $node);
// Clear the static loading cache.
entity_get_controller('node')->resetCache(array($node->nid));
Anyways, if you are trying to update anything other than than fields, this will no work (comment status, published status, etc). Also If you are using node_save, cache for the particular node will be cleared automatically for different methods we need to clear it with 'entity_get_controller'.
Update:
It appears that you should also call field_attach_presave()
to let other modules process the field input properly. File module, for example, uses it to set the file status to permanent using this hook. I have updated my 2 examples above.