J'ai une question liée aux performances. Disons que j'ai un utilisateur avec le prénom Michael. Prenez la requête suivante:
UPDATE users
SET first_name = 'Michael'
WHERE users.id = 123
La requête exécutera-t-elle réellement la mise à jour, même si elle est mise à jour à la même valeur? Si oui, comment puis-je empêcher que cela se produise?
postgresql
performance
update
postgresql-performance
OneSneakyMofo
la source
la source
Réponses:
En raison du modèle MVCC de Postgres et conformément aux règles de SQL, an
UPDATE
écrit une nouvelle version de ligne pour chaque ligne qui n'est pas exclue dans laWHERE
clause.Cela n'ont un impact plus ou moins important sur les performances, directement et indirectement. Les «mises à jour vides» ont le même coût par ligne que toute autre mise à jour. Ils déclenchent des déclencheurs (s'ils sont présents) comme toute autre mise à jour, ils doivent être journalisés WAL et ils produisent des lignes mortes gonflant la table et provoquant plus de travail pour plus tard comme toute autre mise à jour.
VACUUM
Les entrées d'index et les colonnes TOASTed où aucune des colonnes impliquées n'est modifiée peuvent rester les mêmes, mais cela est vrai pour toute ligne mise à jour. En relation:
C'est presque toujours une bonne idée d'exclure ces mises à jour vides (quand il y a une chance réelle que cela se produise). Vous n'avez pas fourni de définition de tableau dans votre question (ce qui est toujours une bonne idée). Nous devons supposer qu'il
first_name
peut être NULL (ce qui ne serait pas surprenant pour un "prénom"), donc la requête doit utiliser une comparaison sûre NULL :Si
first_name IS NULL
avant la mise à jour, un test avec justefirst_name <> 'Michael'
serait évalué à NULL et exclurait ainsi la ligne de la mise à jour. Erreur sournoise. Si la colonne est définieNOT NULL
, utilisez la simple vérification d'égalité, car c'est un peu moins cher.En relation:
la source
Indexes entries and TOASTed columns where none of the involved columns are changed can stay the same
Mais ne devraient-ils pas être mis à jour pour pointer vers le nouvel emplacement de la ligne?rollback
, gestion des instantanés, gestion des verrous, WAL, et quoi d'autre ...Les ORM comme Ruby on Rail proposent une exécution différée qui marque un enregistrement comme modifié (ou non), puis lorsque cela est nécessaire ou appelé, puis soumettez la modification à la base de données.
PostgreSQL est une base de données et non un ORM. Cela aurait diminué les performances s'il avait fallu du temps pour vérifier si une nouvelle valeur était la même que la valeur mise à jour dans votre requête.
Il mettra donc à jour la valeur, qu'elle soit identique ou non à la nouvelle valeur.
Si vous souhaitez empêcher cela, vous pouvez utiliser du code comme Max Vernon l'a suggéré dans sa réponse.
la source
Vous pouvez simplement ajouter à la
where
clause:Si
first_name
est défini commeNOT NULL
, laOR first_name IS NULL
pièce peut être supprimée.La condition:
peut également être écrit plus élégamment comme (dans la réponse d'Erwin):
la source
NULL
@erwinDu point de vue de la base de données
La réponse à ta question est oui. La mise à jour aura lieu. La base de données ne vérifie pas la valeur précédente, elle définit uniquement la nouvelle valeur.
Comme cela se produit dans la mémoire (et ne sera écrit dans les fichiers de données qu'une fois la validation émise), les performances ne seront pas un problème.
Du point de vue ORM
Normalement, vous aurez un objet représentant une seule ligne de la base de données (il peut être beaucoup plus complexe que cela, mais restons simples). Cet objet est géré en mémoire (au niveau du serveur d'applications) et seule la dernière version validée de cet objet parviendra réellement à la base de données à un certain moment.
Cela peut expliquer les différents comportements.
Maintenant, ne comparons pas un cargo avec une imprimante 3D. Le fait que vous puissiez envoyer des imprimantes 3D à l'aide de cargos ne signifie pas qu'il puisse y avoir une sorte de comparaison entre elles.
Prendre plaisir!
J'espère que cela a clarifié certains concepts.
la source