If you are only changing a single field doing a full set_metadata is rather inefficient, though you can avoid some of that inefficiency by making sure that all the other fields of the metadata object are null as documented in the docstring of the apply_metadata_changes method. Still in the new db this will always be slower, because of the auto-commit.
If all you want to do is change a single field, do this:
Code:
db.new_api.set_field('#xyz', {book_id:val for book_id in book_ids})
# Refresh the GUI
cr = self.gui.library_view.currentIndex().row()
self.gui.library_view.model().refresh_ids(list(book_ids), cr)
# Only do this if the Tag Browser could need refreshing (i.e. if the
# column you are updating could be displayed in the Tag Browser
self.gui.tags_view.recount()
This will not popup a progress dialog, but it should not be needed as setting a single field, even for a lot of books, should be pretty quick.