Je dois faire la requête de mise à jour suivante via une procédure stockée:
UPDATE table1 SET name = @name (this is the stored procedure inputparameter) WHERE name IS NULL
Table1 n'a pas d'index ni de clé, 5 colonnes qui sont 4 entiers et 1 varchar (la colonne modifiable 'nom' est la colonne varchar)
Les enregistrements NULL sont environ 15.000.000 lignes qui doivent être mises à jour. Cela prend environ 50 minutes, ce que je pense est trop long.
J'utilise un Azure SQL DB Standard S6 (400DTU).
Quelqu'un peut-il me donner un conseil pour améliorer les performances?
3 Réponses :
Comme vous n'avez pas de clés ou d'index, je peux suggérer l'approche suivante.
1- Créez une nouvelle table en utilisant INTO
(qui copiera les données) comme la requête suivante.
WHILE EXISTS (SELECT 1 FROM table1 WHERE name is null) BEGIN UPDATE TOP (10000) table1 SET name = @name WHERE n ame is null END
2- Supprimer l'ancienne table
exec sp_rename 'dbo.newtable', 'table1'
3- Renommer la nouvelle table en table1 code >
drop table table1
Une autre approche peut être d'utiliser la mise à jour par lots, parfois vous obtenez de meilleures performances par rapport à la mise à jour en masse (vous devez tester en ajustant la taille du lot).
SELECT CASE WHEN NAME IS NULL THEN @name ELSE NAME END AS NAME, <other columns > INTO dbo.newtable FROM table1
pouvez-vous faire avec la méthode suivante?
UPDATE table1 SET name = ISNULL(name,@name)
pour les valeurs nulles, il sera mis à jour avec @name et le reste sera mis à jour avec la même valeur.
Non. Vous mettez à jour 15 000 000 de lignes, ce qui va prendre beaucoup de temps. Chaque mise à jour a une surcharge pour trouver la ligne et enregistrer la valeur.
Avec autant de lignes à mettre à jour, il est peu probable que la surcharge trouve les lignes. Si vous ajoutez un index sur nom
, la mise à jour devra en fait mettre à jour l'index ainsi que mettre à jour les valeurs d'origine.
Si votre souci est de verrouiller la base de données, vous peut mettre en place une boucle où vous faites quelque chose comme ça encore et encore:
UPDATE TOP (100000) table1 SET name = @name (this is the stored procedure inputparameter) WHERE name IS NULL;
100 000 lignes devraient durer environ 30 secondes.
Dans ce cas , un index sur nom
aide . Sinon, chaque itération de la boucle serait essentiellement la lecture de la table entière.
cherchez-vous à mettre à jour toutes les valeurs de nom nulles vers une valeur spécifique ou à mettre à jour un ID particulier?
toutes les valeurs NULL doivent être mises à jour vers @name, soit environ 15 millions d'enregistrements, sans ID particulier
Vous n'avez pas mentionné si vous aviez réellement eu la possibilité de créer un index ou de mettre à l'échelle SQL Server (c'est-à-dire à un niveau P). Ce sont deux étapes pour améliorer les performances
Si j'ai bien fait le calcul, vous mettez à jour 5 000 lignes par seconde. Qu'est-ce qui rend cela trop lent?