Mysql
 sql >> Base de données >  >> RDS >> Mysql

MISE À JOUR MySQL :Les 5 meilleurs conseils pour les développeurs T-SQL

Ajoutez-vous MySQL à votre liste de compétences en bases de données ? Ensuite, l'instruction MySQL UPDATE est l'une des commandes que vous devez apprendre.

Nous poursuivons notre voyage vers MySQL du point de vue de SQL Server. Cela a commencé avec CREATE TABLE, suivi de INSERT, et la pièce la plus récente concernait DELETE. Aujourd'hui, UPDATE est notre point central.

Les différences sont subtiles et faciles à apprendre. Mais tout comme dans les articles précédents, notre objectif est de vous permettre d'être opérationnel rapidement. Mais avant de continuer, clarifions ces éléments :

  • Les exemples utilisés ici ont été exécutés sur MySQL 8.0.23 à l'aide du moteur de stockage InnoDB.
  • Nous avons utilisé SQL Server 2019.

Préparer les exemples de données

Nous ne pouvons pas continuer sans exemples de données. J'aimerais mettre les développeurs T-SQL à l'aise dans cet exercice. Alors, importons quelques tables familières dans AdventureWorks exemple de base de données de SQL Server :

  • Produit
  • SalesOrderHeader
  • Détails de la commande

Pour importer ces tables dans MySQL, j'ai utilisé dbForge Studio for MySQL. Voici les étapes :

  1. Créer une nouvelle base de données appelée adventureworks2019 .
  2. Cliquez avec le bouton droit de la souris sur adventureworks2019 et sélectionnez Outils .
  3. Sélectionnez Importer des données . Une nouvelle fenêtre apparaîtra.
  4. Sélectionnez ODBC . Vous devez créer un DSN utilisateur pour vous connecter à votre serveur SQL et à AdventureWorks base de données.
  5. Cliquez sur Suivant .
  6. Sélectionnez la table que vous devez importer, la connexion MySQL et la base de données cible (adventureworks2019 ).
  7. Cliquez sur Suivant .
  8. Modifiez les paramètres de la colonne. Vous pouvez également voir des exemples de données. Vous pouvez ignorer cela en cliquant sur Suivant ou modifiez les paramètres comme bon vous semble.
  9. Cliquez sur Importer .
  10. Importez le tableau suivant en suivant les mêmes instructions à l'écran.
  11. Cliquez sur Terminer .

Après avoir importé ces tables, vous êtes maintenant prêt pour les exemples de cet article. Alors, commençons.

1. Bases de la syntaxe

La syntaxe de l'instruction MySQL UPDATE ressemble à ceci :

UPDATE [LOW_PRIORITY] [IGNORE] table_references
    SET assignment_list
    [WHERE where_condition]
    [ORDER BY ...]
    [LIMIT row_count]

Je peux presque vous entendre après avoir lu la syntaxe :LOW PRIORITY, IGNORE, ORDER BY et LIMIT ne correspondent pas ! Commençons à discuter par le haut.

Premièrement, LOW_PRIORITY est un mot clé étranger pour nous car SQL Server ne le prend pas en charge. C'est facultatif, mais si vous l'incluez, les mises à jour sont retardées jusqu'à ce que tous les autres clients ne lisent pas la table.

Un autre mot-clé extraterrestre est IGNORE. C'est également facultatif, mais si vous l'incluez et que des doublons se produisent, une erreur ne sera pas générée. Pour plus d'erreurs ignorables, consultez ce lien.

Ensuite, COMMANDER PAR. On sait à quoi ça sert. Mais essayez-le dans SQL Server Management Studio et des lignes sinueuses apparaîtront sous les mots-clés.

Enfin, LIMITER. C'est la même chose que TOP dans SQL Server. Plus d'informations et ORDER BY dans une section ultérieure.

Ce sont les différences évidentes. Poursuivez votre lecture dans les 2 sous-sections suivantes.

Colonne unique de MISE À JOUR MySQL

La mise à jour d'une seule colonne est presque similaire. Ainsi, l'exemple ci-dessous produira le même résultat à partir des deux plates-formes de base de données. Notez cependant qu'au lieu de backticks, SQL Server utilise des crochets.

-- MySQL UPDATE single column
UPDATE `production.product`
SET ReorderPoint = 650
WHERE ProductID = 316;

Voici une syntaxe T-SQL équivalente :

-- T-SQL UPDATE single column
UPDATE [Production].[Product]
SET ReorderPoint = 650
WHERE ProductID = 316;

La valeur affectée à une colonne peut être n'importe quelle expression à valeur unique tant que le type renvoyé est le même que le type de données de la colonne.

MISE À JOUR MySQL Plusieurs Colonnes

La mise à jour de plusieurs colonnes est également presque similaire à T-SQL. Voici un exemple :

UPDATE `production.product`
SET ReorderPoint = 650, SafetyStockLevel = 1200
WHERE ProductID = 316;

Pour mettre à jour plusieurs colonnes, séparez simplement les paires colonne-valeur par une virgule. Encore une fois, la seule différence ici est les backticks.

Jusqu'à présent, ce sont toutes des mises à jour de table unique. Passons à MySQL UPDATE depuis une autre table.

2. MISE À JOUR MySQL avec JOIN

Il existe des différences mineures que vous verrez lors de la mise à jour d'une table avec des jointures. La meilleure façon de le montrer est à travers un exemple d'utilisation de 3 tables.

UPDATE `sales.salesorderdetail` sod
INNER JOIN `sales.salesorderheader` soh ON sod.SalesOrderID = soh.SalesOrderID
INNER JOIN `production.product` p ON sod.ProductID = p.ProductID
set UnitPrice = p.ListPrice
WHERE p.ProductID = 758
AND soh.OrderDate = '2012-04-30';

Notez que certaines clauses sont organisées différemment par rapport à SQL Server. Les jointures apparaissent en premier avant la clause SET. Il n'y a pas non plus de clause FROM. Comme vous pouvez vous y attendre, SQL Server Management Studio placera des lignes sinueuses pour la syntaxe incriminée. Voir ceci et la syntaxe T-SQL correcte dans la figure 1 ci-dessous.

Avant la mise à jour, la valeur du prix unitaire est de 874,7940, comme illustré à la figure 2.

Après la mise à jour, UnitPrice est mis à jour à partir du Produit ListPrice de la table . Voir Figure 3.

Outre INNER JOIN, vous pouvez utiliser LEFT ou RIGHT JOIN selon vos besoins.

3. MISE À JOUR MySQL avec sous-requête

Vous pouvez utiliser l'instruction MySQL UPDATE à partir d'une autre table à l'aide d'une sous-requête. La requête avec une jointure dans la section précédente peut être réécrite à l'aide d'une sous-requête. Les résultats seront les mêmes. Voici :

UPDATE `sales.salesorderdetail` sod
INNER JOIN `sales.salesorderheader` soh ON sod.SalesOrderID = soh.SalesOrderID
SET sod.UnitPrice = (select ListPrice from `production.product` WHERE ProductID = 758)
WHERE sod.ProductID = 758
AND soh.OrderDate = '2012-04-30';

L'approche est différente, mais le résultat est le même que dans la figure 3. Cependant, notez que la sous-requête utilisée pour mettre à jour une colonne doit renvoyer 1 valeur.

Il existe une autre façon d'exprimer cette instruction MySQL UPDATE.

4. MISE À JOUR MySQL avec CTE

Les expressions de table communes (CTE) sont prises en charge dans MySQL et SQL Server. Si vous n'êtes pas familier avec les CTE, consultez l'article précédent.

Maintenant, voici la déclaration équivalente avec CTE utilisé.

WITH priceIncrease AS
(
  SELECT soh.SalesOrderID, p.ProductID, p.ListPrice
  FROM `sales.salesorderdetail` sod
  INNER JOIN `sales.salesorderheader` soh ON sod.SalesOrderID = soh.SalesOrderID
  INNER JOIN `production.product` p ON sod.ProductID = p.ProductID
  WHERE p.ProductID = 758
  AND soh.OrderDate = '2012-04-30'
)
UPDATE `sales.salesorderdetail` s
INNER JOIN priceIncrease pi ON s.SalesOrderID = pi.SalesOrderID AND s.ProductID = pi.ProductID
SET s.UnitPrice = pi.ListPrice

SQL Server prend en charge le même concept, mais sans backticks. Le résultat sera le même que dans la figure 3.

Vous vous demandez peut-être laquelle des 3 approches est la meilleure ? Nous comparerons leurs performances plus en détail.

5. MISE À JOUR MySQL avec LIMIT

MySQL UPDATE peut limiter le nombre de lignes à mettre à jour avec le mot clé LIMIT. Supposons que nous voulions mettre à jour 5 enregistrements dans le Produit table. Nous pouvons exprimer la déclaration comme suit :

UPDATE `production.product` p
SET p.StandardCost = p.StandardCost + 10, p.ListPrice = p.ListPrice + 10
ORDER BY p.ProductID
LIMIT 5;

Cela triera les enregistrements en fonction de ProductID , puis mettez à jour les 5 premiers enregistrements. Il s'arrête après le 5ème enregistrement.

L'homologue SQL Server de LIMIT est TOP. Cependant, vous ne pouvez pas simplement remplacer le mot clé LIMIT par TOP et vous attendre à ce qu'il fonctionne dans SQL Server. Voici la version modifiée en T-SQL qui donnera le même résultat :

UPDATE Production.Product
SET StandardCost += 10, ListPrice += 10
WHERE ProductID IN (SELECT TOP 5 ProductID 
		    FROM Production.Product 
		    ORDER BY ProductID)

La logique est un peu différente. Il met à jour StandardCost et ListePrix colonnes basées sur les ProductID trouvés dans la sous-requête. La sous-requête, quant à elle, renvoie les 5 premiers enregistrements du Produit tableau trié par ProductID .

Bien que TOP soit également pris en charge dans T-SQL UPDATE, ORDER BY ne l'est pas. Ainsi, l'utilisation de TOP avec UPDATE modifiera les enregistrements aléatoires. La syntaxe ci-dessus s'applique aux notices ordonnées avec TOP.

Performances de la MISE À JOUR MySQL

Auparavant, nous avions une instruction UPDATE avec les mêmes résultats même si nous utilisions des méthodes différentes. Nous avons utilisé un JOIN, une sous-requête et un CTE. Lequel d'entre eux sera le plus performant ?

Il existe également un plan d'exécution dans MySQL utilisant le mot-clé EXPLAIN. La syntaxe est la suivante :

EXPLAIN [FORMAT=JSON]
<SQL statement>

Sans le format JSON, vous disposez d'informations de base telles que les tables, les clés d'index utilisées et les lignes analysées. Lorsque le format JSON est spécifié, vous disposez d'informations plus détaillées. dbForge Studio for MySQL inclut un Query Profiler en plus du résultat d'EXPLAIN. MySQL Workbench inclut un EXPLAIN visuel où vous pouvez voir une vue graphique du plan basé sur EXPLAIN FORMAT=JSON.

Maintenant que nous connaissons les instructions de ligne de commande et les outils graphiques, comment pouvons-nous les utiliser pour comparer différentes méthodes ?

Avant de continuer, permettez-moi d'être honnête. Ma maîtrise de SQL Server est supérieure à celle de MySQL. Je peux manquer quelque chose en cours de route ou me tromper. Vous pouvez combler les lacunes dans la section Commentaires plus tard.

Disséquer les résultats EXPLAIN pour UPDATE avec JOIN

La première fois que j'ai exécuté l'instruction MySQL UPDATE avec JOIN, il a fallu 11,3 secondes pour 24 lignes mises à jour. Incroyable, n'est-ce pas ?

Voici ce qui s'est passé comme vu dans dbForge Studio. Consultez la figure 4 ci-dessous.

Que nous dit la figure 4 ?

  1. Les 3 alias de table utilisés sont là. Tous les 3 ont accès aux types ALL. Cela signifie que MySQL a utilisé Table Scan pour les 3.
  2. Regardez la clé colonne. Rien n'est affiché sur les 3 tables, ce qui signifie qu'aucune clé d'index n'a été utilisée. Cela prend en charge le point précédent de l'analyse de table.
  3. Enfin, les lignes colonne. Il indique combien de lignes MySQL pense qu'il doit analyser pour obtenir le résultat final. Pour 24 lignes mises à jour, des milliers de lignes ont été analysées pour SalesOrderHeader et SalesOrderDetails . Pendant ce temps, toutes les lignes du Produit table ont été scannés.

Je me suis gratté la tête en apprenant cela. J'ai réalisé que lorsque j'importais des tables depuis SQL Server, seules la structure de la table et les données étaient importées, pas les index .

J'ai donc créé des index et des clés primaires appropriés dans dbForge Studio. Voici ce que j'ai créé :

  • J'ai créé le ProductID dans le Produit table une clé primaire.
  • J'ai également ajouté SalesOrderID comme clé primaire dans le SalesOrderHeader table. Ensuite, j'ai fait un index pour OrderDate aussi.
  • Enfin, j'ai créé SalesOrderDetailID dans le SalesOrderDetail table une clé primaire. J'ai également ajouté un index pour le SalesOrderID et ProductID colonnes de ce tableau.

Après cela, j'ai généré un nouveau plan d'exécution pour la même requête pour voir les améliorations. Le résultat ?

ACCÉLÉRER LA VITESSE APRÈS AVOIR AJOUTÉ DES INDEX

Le temps d'exécution a été réduit de 11,3 secondes à 0,019 seconde. Très cool !

Vérifions le nouveau plan à l'aide de dbForge Studio dans la figure 5 ci-dessous.

Que nous dit la figure 5 ?

  • L'accès types de 3 tables ont été modifiées. Les 2 valeurs à éviter ici sont ALL et INDEX, surtout sur les grandes tables. ALL est un balayage de table et INDEX est un balayage d'index.
  • La clé colonne inclut désormais les index utilisés. C'est bon. Tous les index ajoutés ont été utilisés.
  • Les lignes colonne montre maintenant des chiffres plus petits. Les index ajoutés ont réduit beaucoup d'E/S sur notre requête.

Pour plus d'informations sur les détails et les valeurs EXPLAIN, consultez cette documentation officielle.

Mais comment cela se compare-t-il à MySQL UPDATE avec sous-requête ?

Disséquer les résultats EXPLAIN pour UPDATE avec sous-requête

La requête précédente pour mettre à jour le UnitPrice colonne a une autre alternative de requête, qui utilise une sous-requête. Comment se compare-t-il au JOIN ? Consultez la figure 6 ci-dessous.

La figure 6 montre :

  • Les valeurs des colonnes de type, de clé et de lignes sont les mêmes par rapport à l'utilisation de JOIN. C'est logique puisqu'il devrait avoir les mêmes résultats.
  • Le temps d'exécution a pris un peu plus de temps. Cela n'arrivera pas à chaque fois, cependant. Cela dépend des ressources actuellement disponibles. La différence de vitesse est également négligeable. Vous ne le sentirez pas du tout.

Une autre méthode consiste à utiliser EXPLAIN FORMAT=JSON pour obtenir plus d'informations sur le plan. Après vérification, le coût de la requête (84,79) et les valeurs des informations de coût sont les mêmes.

Maintenant, comparons-le avec MySQL UPDATE avec CTE.

Disséquer les résultats EXPLAIN pour UPDATE avec CTE

Utiliser le CTE comme base pour mettre à jour le UnitPrice colonne revient à avoir d'abord une table temporaire, puis à joindre la table temporaire à SalesOrderDetails . À première vue, il peut sembler que ce n'est pas une bonne option par rapport aux deux premiers. Mais cela nous montre qu'il est possible d'avoir une mise à jour dans MySQL en utilisant CTE. Cela peut être une bonne option dans d'autres situations. Quoi qu'il en soit, ayons les résultats EXPLAIN pour cette approche.

Si vous n'avez pas dbForge Studio pour MySQL, vous pouvez essayer de produire des résultats EXPLAIN en utilisant la commande dans n'importe quel autre éditeur. Voici un exemple :

EXPLAIN
WITH priceIncrease AS
(
  SELECT soh.SalesOrderID, p.ProductID, p.ListPrice
  FROM `sales.salesorderdetail` sod
  INNER JOIN `sales.salesorderheader` soh ON sod.SalesOrderID = soh.SalesOrderID
  INNER JOIN `production.product` p ON sod.ProductID = p.ProductID
  WHERE p.ProductID = 758
  AND soh.OrderDate = '2012-04-30'
)
UPDATE `sales.salesorderdetail` s
INNER JOIN priceIncrease pi ON s.SalesOrderID = pi.SalesOrderID AND s.ProductID = pi.ProductID
SET s.UnitPrice = pi.ListPrice

Le résultat est dans la figure 7 ci-dessous.

La figure 7 montre :

  • 4 tables ont été utilisées au lieu de 3. La première utilisation de SalesOrderDetail se trouve dans le CTE, puis dans l'instruction UPDATE.
  • Plus de tables signifient plus de lignes par rapport aux 2 approches précédentes.

Étonnamment, cela a fonctionné à 0,015 seconde (non représenté sur la figure). Il en va de même avec l'utilisation d'une sous-requête. Cependant, cela ne se produira pas à chaque fois. Cela dépend des ressources système disponibles au moment de l'exécution.

Le coût total de la requête est de 166,69. C'est plus élevé que les 2 approches précédentes. Plus le coût de la requête est faible, meilleures sont les performances dans le temps.

À emporter

Nous avons approfondi les différences entre MySQL et l'instruction UPDATE de SQL Server. Nous avons appris comment procéder lors de la mise à jour

  • une seule colonne
  • plusieurs colonnes
  • tables avec jointure
  • colonnes utilisant une sous-requête
  • tableaux avec CTE
  • avec une LIMITE

Dans cet article, vous avez également eu un aperçu d'EXPLAIN et de la façon de l'utiliser pour comparer différentes approches UPDATE.

J'espère que cela pourra vous être utile lorsque vous apprendrez MySQL provenant de SQL Server. Si vous aimez cet article, partagez-le sur vos plateformes de médias sociaux préférées. Et si quelque chose manque, faites-le nous savoir dans la section Commentaires.

Bon codage !