Tengo una simple pregunta sobre la forma más eficiente de realizar una unión en particular.Únete entre la tabla de mapeo (unión) con cardinalidad específica
Tome estas tres tablas, nombres reales han sido cambiados para proteger a los inocentes:
Tabla: animal
animal_id name ... ====================== 1 bunny 2 bear 3 cat 4 mouse
Tabla: etiquetas
tag_id tag ================== 1 fluffy 2 brown 3 cute 4 small
tabla de asignación: animal_tag
animal_id tag_id ================== 1 1 1 2 1 3 2 2 3 4 4 2
Quiero encontrar todos los animales etiquetados como 'mullido', 'marrón' y 'lindo'. Es decir que el animal debe etiquetarse con los tres. En realidad, la cantidad de etiquetas requeridas puede variar, pero debería ser irrelevante para esta discusión. Esta es la pregunta que se me ocurrió:
SELECT * FROM animal
JOIN (
SELECT at.animal_id FROM animal_tag at
WHERE at.tag_id IN (
SELECT tg.tag_id FROM tag tg
WHERE tg.tag='fluffy' OR tg.tag='brown' OR tg.tag='cute'
)
GROUP BY at.animal_id HAVING COUNT(at.tag_id)=3
) AS jt
ON animal.animal_id=jt.animal_id
sobre una mesa con animales '' miles y cientos y de 'etiquetas', esta consulta realiza respetable ... 10s de milisegundos. Sin embargo, cuando miro el plan de consulta (Apache Derby es el DB), el costo estimado del optimizador es bastante alto (9945.12) y el plan bastante extenso. Para una consulta así de "simple", generalmente intento obtener planes de consulta con un costo estimado de dígitos simples o dobles.
Así que mi pregunta es, ¿hay una mejor manera de realizar esta consulta? Parece una consulta simple, pero he estado perplejo por encontrar algo mejor.
creo que deberías usar 'AND' en lugar de' OR' en 'WHERE tg.tag = 'fluffy' O tg.tag = 'marrón' O tg.tag = 'cute'' –
@johntotetwoo No _single_ fila en 'tag' coincide con más de un valor único, por lo que usar AND no produciría filas coincidentes. –
@BrankoDimitrijevic ¡tienes razón! mi error. que estoy pensando. –