En MySQL 5.0.75-0ubuntu10.2
j'ai une disposition de table fixe comme ça:MySQL: Utilisation des indices UNION subselects
Table parent
avec un identifiant Table parent2
avec un identifiant Table children1
avec un parentId
CREATE TABLE `Parent` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(200) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB
CREATE TABLE `Parent2` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(200) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB
CREATE TABLE `Children1` (
`id` int(11) NOT NULL auto_increment,
`parentId` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `parent` (`parentId`)
) ENGINE=InnoDB
un enfant a un parent dans l'une des tables Parent
ou Parent2
. Quand je dois obtenir un enfant que j'utilise une requête comme ça:
select * from Children1 c
inner join (
select id as parentId from Parent
union
select id as parentId from Parent2
) p on p.parentId = c.parentId
Expliquer ce rendement de la requête:
+----+--------------+------------+-------+---------------+---------+---------+------+------+-----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------+------------+-------+---------------+---------+---------+------+------+-----------------------------------------------------+
| 1 | PRIMARY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables |
| 2 | DERIVED | Parent | index | NULL | PRIMARY | 4 | NULL | 1 | Using index |
| 3 | UNION | Parent2 | index | NULL | PRIMARY | 4 | NULL | 1 | Using index |
| NULL | UNION RESULT | <union2,3> | ALL | NULL | NULL | NULL | NULL | NULL | |
+----+--------------+------------+-------+---------------+---------+---------+------+------+-----------------------------------------------------+
4 rows in set (0.00 sec)
qui est raisonnable compte tenu de la mise en page.
Maintenant le problème: La requête précédente est un peu inutile, car il renvoie aucune colonne des éléments parents. En ce moment, j'ajouter plusieurs colonnes à la requête intérieure aucun index sera utilisé plus:
mysql> explain select * from Children1 c inner join (select id as parentId,name from Parent union select id as parentId,name from Parent2) p on p.parentId = c.parentId;
+----+--------------+------------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------+------------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| 1 | PRIMARY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables |
| 2 | DERIVED | Parent | ALL | NULL | NULL | NULL | NULL | 1 | |
| 3 | UNION | Parent2 | ALL | NULL | NULL | NULL | NULL | 1 | |
| NULL | UNION RESULT | <union2,3> | ALL | NULL | NULL | NULL | NULL | NULL | |
+----+--------------+------------+------+---------------+------+---------+------+------+-----------------------------------------------------+
4 rows in set (0.00 sec)
Quelqu'un peut-il expliquer pourquoi les indices (primaire) ne sont pas utilisés plus? Y a-t-il une solution de contournement pour ce problème si possible sans avoir à changer la disposition DB?
Merci!
Vous avez probablement raison. Pourquoi j'ai posé la question: j'ai un modèle Hibernate qui produit ces requêtes mais beaucoup plus compliquées qu'ici. J'ai réfléchi à la façon d'améliorer la génération de requêtes de Hibernate pour le mappage de l'héritage de la sous-classe union à la lumière des capacités de MySQL. Mais depuis Hibernate et MySQL ont leurs lacunes dans cette direction, j'ai depuis abandonné l'effort et juste réarrangé la structure de la base de données. Merci de prendre le temps. – jrudolph