Pour les opérations de connexion, nous mettons les conditions d'association de la table pilotante et de la table pilotée après. Si vous ajoutez des conditions de filtrage supplémentaires pour la table pilotante et la table pilotée, mettez-les après sur ou. où. Aucune erreur ne sera signalée, mais l’ensemble de résultats obtenu est différent ? ? ?
Comme nous le savons tous, mysql est basé sur l'algorithme Nested-Loop Join (Nested-Loop Join, quel que soit l'algorithme d'optimisation) pour effectuer les opérations de connexion entre les tables. :
Sélectionnez la table pilote et utilisez les conditions de filtre liées à la table pilote pour exécuter une requête sur une seule table sur la table pilote
Pour chaque enregistrement de la table pilote interrogée, recherchez les enregistrements correspondants dans ; la table entraînée.
Le pseudo-code est le suivant :
for each row in t1 { // 遍历满足对t1单表查询结果集中的每一条纪录 for each row in t2 { // 对于某条t1纪录,遍历满足对t2单表查询结果集中的每一条纪录 if row satisfies join conditions, send to client } }
L'instruction SQL que nous écrivons sera transmise à l'exécuteur pour exécution après avoir été optimisée par l'optimiseur, et la commande show warns peut aider nous obtenons l'optimiseur SQL optimisé.
La structure de la table est la suivante :
CREATE TABLE `student` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `stu_code` varchar(20) NOT NULL DEFAULT '', `stu_name` varchar(30) NOT NULL DEFAULT '', `stu_sex` varchar(10) NOT NULL DEFAULT '', `stu_age` int(10) NOT NULL DEFAULT '0', `stu_dept` varchar(30) NOT NULL DEFAULT '', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `uq_stu_code` (`stu_code`) ) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=utf8mb4 CREATE TABLE `course` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `cou_code` varchar(20) NOT NULL DEFAULT '', `cou_name` varchar(50) NOT NULL DEFAULT '', `cou_score` int(10) NOT NULL DEFAULT '0', `stu_code` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`) USING BTREE, KEY `idx_stu_code_cou_code` (`stu_code`,`cou_code`) ) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4
Les données de la table sont les suivantes :
select * from student inner join course on student.stu_code = course.stu_code and student.stu_code >= 3 and course.cou_score >= 80;
Exécutez la commande show warns :
Analyse :
À partir de l'analyse des avertissements de show, pour l'intérieur rejoindre la connexion, après optimisation par l'optimiseur, sur La condition de connexion sera convertie en où ! En d'autres termes, où et on dans les connexions internes sont équivalents
. 4. La différence entre la jointure gauche sur et où 对于inner join连接,经过优化器优化后,on连接条件会转化为where!也就是说内连接中的where和on是等价的
。
sql如下:
select * from student left join course on student.stu_code = course.stu_code where student.stu_code >= 3;
执行explain+sql命令:
执行show warnings命令:
结果集:
分析:从explain分析看出,student作为驱动表,把student.stu_code >= 3作为过滤条件进行全表扫描,然后把查询到的每条纪录的student.stu_code(也就是on条件里面的)分别作为过滤条件让被驱动表course做单表查询。
sql如下:
select * from student left join course on student.stu_code = course.stu_code and student.stu_code >= 3;
执行explain+sql命令:
执行show warnings命令:
结果集:
从结果集来看,student.stu_code >= 3并未生效,为什么?
分析:从explain分析看出,student作为驱动表,做全表扫描,然后把查询到的每条记录的student.stu_code和student.stu_code >= 3(也就是on条件里面的)分别做为过滤条件让被驱动表做单表查询;此时student.stu_code >= 3对驱动表是不过滤的,仅在连接被驱动表时生效,查询不到符合纪录而返回NULL!
4.1 où les conditions de filtrage de la table des pilotes
Exécuter la commande show warns :
Ensemble de résultats : Analyse : À partir de l'analyse d'explication Out, student est utilisé comme table pilote, student.stu_code >= 3 est utilisé comme condition de filtre pour effectuer une analyse complète de la table, puis le student.stu_code de chaque enregistrement interrogé (c'est-à-dire le une dans la condition on) est utilisée comme condition de filtre à piloter. Effectuer une requête de table unique sur le parcours de table. Analyse : De l'analyse d'explication, on peut voir que student est utilisé comme table pilote pour effectuer une analyse complète de la table, puis student.stu_code et course.cou_score >= 80 (c'est-à-dire dans la condition on ) de chaque enregistrement interrogé sont séparément Utilisez la table pilotée comme condition de filtre pour effectuer une requête de table unique ; sql est la suivante : Exécuter la commande explicative+sql : Exécuter la commande show warns : Ensemble de résultats : De l'analyse des avertissements show ? La connexion de jointure gauche devient une connexion de jointure interne ? Analyse : à partir de l'analyse des avertissements d'affichage, on peut voir que si la table pilotée a des conditions de filtre dans lesquelles, alors la jointure gauche sera invalidée et optimisée dans une connexion de jointure interne. Alors Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!select * from student
left join course on student.stu_code = course.stu_code
and course.cou_score >= 80;
Pour le moment, student.stu_code >= 3 n'est pas filtré pour la table pilote. Il ne prend effet que lors de la connexion. à la table pilotée. Si aucun enregistrement correspondant n'est trouvé dans la requête, elle sera renvoyée.
🎜🎜4.3 sur les conditions de filtre de table pilotée 🎜🎜🎜sql sont les suivantes : 🎜🎜rrreee🎜🎜Exécuter la commande explicative+sql : 🎜🎜🎜🎜🎜🎜🎜Exécuter la commande show warns : 🎜🎜🎜🎜 🎜 🎜🎜 Résultats Épisode : 🎜🎜🎜🎜🎜4.4 où la condition de filtre de table pilotée
被驱动表的过滤条件应该放在on而不是where
.