Interviewer: Savez-vous comment la déclaration de sélection et la déclaration de mise à jour sont exécutées?

Récemment, un fan a interviewé une société Internet et s'est vu demander: Savez-vous comment la déclaration select et la déclaration de mise à jour sont exécutées? , Si je veux écrire un article sur la différence entre les deux instructions SQL d'exécution, cela ne viendra pas.

En général, la logique exécutée par select et update est à peu près la même, mais l'implémentation spécifique est toujours différente.

Bien sûr, une compréhension approfondie de la différence spécifique entre select et update ne se limite pas aux entretiens. Lorsque vous voulez que Mysql soit exécuté efficacement, le meilleur moyen est de comprendre clairement comment Mysql exécute les requêtes, uniquement pour avoir une compréhension plus complète de chaque exécution SQL Afin de mieux optimiser SQl.

sélectionner l'instruction

Lorsque le SQl d'une requête est exécuté, les étapes suivantes se produisent probablement:

  1. Le client envoie une instruction de requête au serveur.
  2. Le serveur vérifie d'abord le nom d'utilisateur et le mot de passe et vérifie l'autorité.
  3. Ensuite, il vérifie si la requête existe dans le cache et, si elle existe, renvoie le résultat qui existe dans le cache. S'il n'existe pas, passez à l'étape suivante.
  4. Ensuite, il analyse la grammaire et la méthode lexicale, analyse SQl, la détection grammaticale et le prétraitement, puis génère le plan d'exécution correspondant par l'optimiseur.
  5. L'exécuteur Mysql s'exécute selon le plan d'exécution généré par l'optimiseur et appelle l'interface du moteur de stockage pour la requête.
  6. Le serveur renvoie le résultat de la requête au client.

Processus d'exécution MySQL

L'exécution des instructions dans Mysql est une exécution hiérarchique et les tâches effectuées par chaque couche sont différentes. Jusqu'à ce que le résultat final soit renvoyé, il est principalement divisé en couche service et couche moteur. La couche service comprend: connecteur, analyseur, Optimiseur, exécuteur. La couche moteur est compatible avec divers moteurs de stockage sous forme de plug-ins.

L'organigramme de l'exécution de Mysql est illustré dans la figure suivante:

Voici un exemple pour illustrer le processus d'exécution de Mysql, créez une table User, comme suit:

// 新建一个表
DROP TABLE IF EXISTS User;
CREATE TABLE `User` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  `age` int DEFAULT 0,
  `address` varchar(255) DEFAULT NULL,
  `phone` varchar(255) DEFAULT NULL,
  `dept` int,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8;

// 并初始化数据,如下
INSERT INTO User(name,age,address,phone,dept)VALUES('张三',24,'北京','13265543552',2);
INSERT INTO User(name,age,address,phone,dept)VALUES('张三三',20,'北京','13265543557',2);
INSERT INTO User(name,age,address,phone,dept)VALUES('李四',23,'上海','13265543553',2);
INSERT INTO User(name,age,address,phone,dept)VALUES('李四四',21,'上海','13265543556',2);
INSERT INTO User(name,age,address,phone,dept)VALUES('王五',27,'广州','13265543558',3);
INSERT INTO User(name,age,address,phone,dept)VALUES('王五五',26,'广州','13265543559',3);
INSERT INTO User(name,age,address,phone,dept)VALUES('赵六',25,'深圳','13265543550',3);
INSERT INTO User(name,age,address,phone,dept)VALUES('赵六六',28,'广州','13265543561',3);
INSERT INTO User(name,age,address,phone,dept)VALUES('七七',29,'广州','13265543562',4);
INSERT INTO User(name,age,address,phone,dept)VALUES('八八',23,'广州','13265543563',4);
INSERT INTO User(name,age,address,phone,dept)VALUES('九九',24,'广州','13265543564',4);

Maintenant, lancez une requête SQl sur cette table:查询每个部门中25岁以下的员工个数大于3的员工个数和部门编号,并按照人工个数降序排序和部门编号升序排序的前两个部门。

SELECT dept,COUNT(phone) AS num FROM User WHERE age< 25 GROUP BY dept HAVING num >= 3 ORDER BY num DESC,dept ASC LIMIT 0,2;

Connecteur

Lorsque vous commencez ce SQL, vous vérifierez d' abord que votre nom d'utilisateur et votre mot de passe sont corrects , s'ils sont incorrects, le message d'erreur s'affiche "Access denied for user":;

Si le nom d'utilisateur et le mot de passe sont vérifiés, il ira à la table des autorisations pour obtenir les autorisations de l'utilisateur actuel et vérifier si l'instruction a l'autorisation. S'il n'y a pas d'autorisation, elle renverra directement un message d'erreur. S'il y a une autorisation, elle passera à l'étape suivante. La première étape est effectuée dans le connecteur illustré à la figure 1, pour vérifier les autorisations de l'utilisateur connecté.

Remarque: Les opérations ultérieures dépendent de la portée de cette autorité.

Récupérer le cache

Lorsque la connexion est établie et que l'instruction de requête est exécutée, il vérifie d'abord dans la zone de cache pour voir si le SQL a été exécuté. S'il a déjà été exécuté, son résultat d'exécution sera Key-Valueappliqué en douceur à la mémoire sous la forme de clé 执行的sqlet valeur 结果集.

Si la clé du cache est atteinte, le résultat sera directement renvoyé au client. S'il est manqué, l'opération de suivi sera effectuée. Une fois l'opération terminée, le résultat sera mis en cache pour une nouvelle requête et une nouvelle obtention, la prochaine fois que la requête sera également exécutée Une telle opération en boucle.

Remarque : Le cache de Mysql est plus adapté aux tables statiques, tables qui ne sont pas fréquemment mises à jour, car tant que la table actuelle contient des mises à jour de données, le cache de la table deviendra invalide. Si la table est mise à jour fréquemment, le cache est fréquemment efficace, le cache est donc conservé Les performances de consommation sont bien supérieures à l'optimisation des performances apportées par l'utilisation du cache, de sorte que le gain ne vaudra pas la perte, ce qui affectera sérieusement les performances de Mysql, donc le cache est coupé dans la version Mysql 8.

D'un point de vue personnel, le point de vue sur le cache est qu'il n'est pas nécessaire de le couper. Vous pouvez le configurer pour désactiver le cache par défaut, puis l'activer lorsque vous en avez besoin, et vous pouvez spécifier quelles tables utiliser le cache via des paramètres de configuration, et ces tables n'utilisent pas le cache. Cela peut être plus efficace d'utiliser le cache.

Analyseur

L'analyseur comporte deux étapes principales: (1) 词法分析(2)语法分析

L' analyse lexicale est principalement réalisée 提炼关键性字, par exemple sélectionner, 提交检索的表,, 提交字段名, a 提交检索条件déterminé que la déclaration est mise à jour ou sélectionner ou DELETE.

La principale effectuer une analyse syntaxique de vous identifier 输出的sql与否准确, si 合乎mysql的语法, si ne répond pas à la syntaxe SQL lancera: You have an error in your SQL syntax.

Optimiseur

L'optimiseur de requêtes convertira l'arborescence d'analyse en un plan d'exécution. Une requête peut avoir plusieurs méthodes d'exécution, et toutes renvoient le même résultat à la fin. Le rôle de l'optimiseur est de les trouver 最好的执行计划.

Par exemple: lorsqu'il y a plusieurs index dans l'instruction de requête, l'optimiseur décide quel index utiliser, ou lorsqu'il existe plusieurs associations de tables, le choix de l'ordre de connexion des tables et les autres opérations sont toutes déterminées par l'optimiseur .

Le processus de génération d'un plan d'exécution prend plus de temps, en particulier lorsqu'il existe de nombreux plans d'exécution alternatifs. Si le plan d'exécution final correspondant à l'instruction est mis en cache lors de l'exécution d'une instruction SQL.

Lorsqu'il 相似的语句est à nouveau entré dans le serveur, il peut l'être directement 使用已缓存的执行计划, ignorant ainsi tout le processus de génération du plan d'exécution de l'instruction SQL, améliorant ainsi la vitesse d'exécution de l'instruction.


MySQL utilise un optimiseur de requêtes basé sur les coûts. Il essaiera de prédire le coût d'une requête en utilisant un certain plan d'exécution et de choisir celui avec le moins de coûts.

Actionneur

Le plan d'exécution généré par l'optimiseur est remis à l'exécuteur pour exécution. L'exécuteur appelle l'interface de lecture du moteur de stockage et l'interface de lecture du moteur de stockage est appelée cycliquement dans l'exécuteur en échange de lignes de données qui remplissent les conditions et la place dans un Dans le jeu de résultats, toutes les lignes de données qui remplissent les conditions sont parcourues et obtenues, et enfin le jeu de résultats est renvoyé pour mettre fin à l'ensemble du processus de requête.

déclaration de mise à jour

Nous avons terminé l'instruction select ci-dessus. Le processus d'exécution de l'instruction select passera par le connecteur, l'analyseur, l'optimiseur, l'exécuteur et le moteur de stockage. La même instruction de mise à jour passera également par le processus d'exécution de l'instruction select.


Mais la plus grande différence avec select est que l'instruction de mise à jour implique deux opérations de journal redo log(redo log) et binlog (archive log) . Pour l'introduction détaillée de ces deux journaux, j'ai écrit un article pour le présenter avant, et ceux qui sont intéressés peuvent jeter un œil à []:

Alors, comment utilisez-vous redo logsum dans Mysql binlog? Pourquoi utiliser redo logsum binlog? Ne suffit-il pas d'effectuer la mise à jour directement et de l'enregistrer? Aussi placé redo loget binlog, cela ne vous dérange pas? Permettez-moi de parler lentement, il contient de nombreux articles.

refaire le journal

Tout le monde sait que Mysql est une base de données relationnelle, qui est utilisée pour stocker des données. Lorsque la quantité d'accès à la base de données est importante, l'efficacité de l'accès au disque en lecture et en écriture de Mysql est très faible et les conditions de SQL filtrent les données, donc l'efficacité C'est encore plus bas.

Voilà pourquoi l'introduction de la base de données non relationnelle comme des raisons de cache de données, telles que: Redis, MongoDBet ainsi de suite, est de réduire la base de données SQL io opérations en cours d' exécution .

De la même manière, si chaque instruction de mise à jour est exécutée, des opérations disk io et un filtrage des données sont nécessaires, et une petite quantité d'accès et de base de données de volume de données peut être prise en charge, alors la quantité d'accès et la quantité de données sont importantes, donc la base de données Je ne peux certainement pas le supporter .

Sur la base des problèmes ci-dessus, un redo logjournal est apparu . La journalisation est également appelée technologie WAL ( Write- Ahead Logging). Il s'agit d' une technologie qui écrit d'abord le journal, met à jour la mémoire, puis met à jour le disque. Le disque de mise à jour est souvent lorsque Mysql est relativement inactif. Cela réduit considérablement la pression sur Mysql.

Les caractéristiques du redo log sont : le redo log est une taille fixe, un journal physique, appartenant au moteur InnoDB, et l'écriture du redo log est une forme d'écriture circulaire du journal :

Comme le montre la figure ci-dessus: s'il y a quatre groupes de redo logfichiers, un groupe a une taille de 1G, alors les quatre groupes ont une taille de 4G, parmi lesquels se write postrouve la position actuelle de l' enregistrement, et les données sont écrites à la position actuelle, alors write pos sera écrit lors de l'écriture Reculez .

Et check pointc'est la position effacée , car le journal de restauration a une taille fixe, donc lorsque le journal de restauration est plein, c'est-à-dire, écrivez le point de contrôle de rattrapage de pos lorsque la nécessité de supprimer une partie des données de journalisation, les données claires seront conservées sur le disque , Et puis déplacez le point de contrôle vers l'avant .

Le journal de rétablissement se rend compte que même lorsque la base de données est anormalement en panne, les enregistrements précédents ne seront pas perdus après le redémarrage, qui est la capacité de sécurité en cas de panne.

binlog

Binlog est appelé un journal d'archivage, qui est un journal logique. Il appartient au journal de niveau serveur de Mysql. Il enregistre la logique d'origine de SQL. Il existe deux modes principaux. Le premier est le format de l'instruction qui enregistre le SQL d'origine et le format de ligne est Enregistrez le contenu de la ligne .

Il semble donc que bien que le redo log et le binlog enregistrent des formes et des contenus différents, les deux journaux peuvent récupérer des données via leur propre contenu enregistré, alors pourquoi ces deux journaux existent-ils en même temps? Tant que l'un d'eux ne fonctionne pas, les deux existent en même temps. Écoutez-moi lentement, il contient également de nombreux articles.

Parce que MyISAM, le moteur fourni avec Mysql, n'a pas de fonction anti-crash, et Mysql n'a pas de moteur InnoDB auparavant, et le journal binlog fourni avec Mysql n'est utilisé que pour archiver les journaux, donc le moteur InnoDB rétablit également les journaux par lui-même. Pour réaliser la fonction de sécurité en cas de collision .

mettre à jour le processus d'exécution

Les fonctions et caractéristiques des deux journaux ont été mentionnées depuis si longtemps, alors quelle est la relation entre ces deux journaux et l'instruction d'exécution de mise à jour?

Regardons d'abord l'image:

prémisse: le moteur actuel utilise InnoDB La différence entre l'instruction update et l'instruction select est principalement que l'utilisation de ces deux logs se reflète principalement dans l'interaction entre l'exécuteur et le moteur. Si l'instruction de mise à jour simple suivante est exécutée:

update user set age=age+1 where id =2;

Comme mentionné ci-dessus, l'instruction de mise à jour de processus transmise par l'instruction select sera également exécutée à nouveau. En ce qui concerne l'exécuteur:

  1. L'exécuteur appellera l'interface de lecture du moteur et trouvera la ligne de données avec id = 2. Comme id est l'index de clé primaire, l'index trouve cette ligne en fonction de la recherche dans l'arborescence. Si la ligne de données existe déjà dans la page de données de la mémoire, le résultat sera renvoyé immédiatement S'il n'est pas dans la mémoire, il sera chargé du disque dans la mémoire, puis le résultat de la requête sera renvoyé .
  2. Ensuite, l'exécuteur ajoute +1 au champ age du résultat renvoyé et appelle l'interface d'écriture du moteur pour écrire la ligne de données mise à jour.
  3. Moteur pour obtenir les lignes de données mises à jour en mémoire et mises redo logà jour dans et les actionneurs peuvent valider la transaction à tout moment, cette fois redo logdans l' prepareétape.
  4. Après avoir reçu la notification du moteur, l'exécuteur génère un binlogjournal et appelle l'interface du moteur pour soumettre la transaction, et le moteur change redo logl'état en commitétat, de sorte que l'opération de mise à jour est terminée.


Par rapport à l'instruction select, étant donné que la sélection ne met pas à jour les données, elle ne renvoie que les données interrogées par le moteur à l'exécuteur même une fois qu'elle est terminée. La mise à jour implique la mise à jour des données et rappelle l'interface du moteur pour écrire le processus d'interaction dans le moteur de stockage.

Engagement en deux phases

Ce qui précède a mentionné le processus d'exécution de l'instruction de mise à jour en détail et a mentionné les deux phases de préparation et de validation de la journalisation. Il s'agit d'une validation en deux phases. La validation en deux phases a pour objectif de garantir que les journaux de journalisation et binlog maintiennent la cohérence des données.

Si l’écriture du journal de restauration réussit et que l’écriture du journal du binai échoue, ou que le journal de restauration échoue et que le journal du bin est écrit avec succès, les données de résultat obtenues à l’aide des deux journaux pour la récupération de données sont incohérentes. Par conséquent, pour vous assurer que les deux journaux sont logiquement cohérents, utilisez deux Présentation de l'étape.

Résumé de la journalisation et du binlog

Enfin, comparons ces deux journaux: redo est physique, binlog est logique, la taille de redo est fixe et les données sont écrites sous une forme circulaire. Lorsque les données sont pleines, les données du journal de redo doivent être effacées et effacées. Les données supprimées sont conservées sur le disque .

Le binlog est écrit sous la forme de journaux supplémentaires, c'est-à-dire que lorsque le journal est écrit à une certaine taille, il passe au suivant et n'écrase pas le journal précédemment écrit.

Binlog est utilisé dans la couche serveur de Mysql. Étant donné que binlog n'a pas de fonction anti-crash, le moteur InnoDB implémente la fonction anti-crash de redo log par lui-même, afin de garantir que les deux journaux sont logiquement cohérents en utilisant une validation en deux phases .

Lorsque vous utilisez les journaux redo et binlog, vous pouvez définir la innodb_flush_log_at_trx_commitsomme des paramètres sync_binlogsur 1, ce qui signifie que le journal sera conservé sur le disque à chaque fois qu'une transaction est validée.

Eh bien, voici une introduction détaillée à la différence entre les instructions d'exécution de sélection et de mise à jour, ce numéro est ici, notre prochaine période, bienvenue à transmettre et à partager.

Je suppose que tu aimes

Origine blog.csdn.net/qq_43255017/article/details/109303138
conseillé
Classement