SQL - Duda sobre rendimiento de consulta

   
Vista:
Imágen de perfil de Walter

Duda sobre rendimiento de consulta

Publicado por Walter (4 intervenciones) el 10/11/2015 15:04:38
Buenas tardes, estoy practicando con la base de datos PUBS de SQL y tengo un ejercicio que me pide listar los libros que fueron escritos o publicados en 'California'.

Adjunto el DER de la parte que me interesa.
Der-pubs

Si yo ejecuto estas dos consultas

1
2
3
4
5
6
7
SELECT		title
FROM		titles ti,
		titleauthor ta,
		authors au
WHERE		ti.title_id = ta.title_id
AND		ta.au_id = au.au_id
AND		au.state = 'CA'

1
2
3
4
5
SELECT		title
FROM		titles ti,
		publishers pu
WHERE		ti.pub_id = pu.pub_id
AND		pu.state = 'CA'

Me dan bien los resultados, pero al intentar combinar esos resultados en una sola consulta me obliga a incluir la cláusula DISTINCT ya que si no lo hago los resultados se combinan y me tira como 1000 registros.

1
2
3
4
5
6
7
8
9
10
SELECT		DISTINCT(title)
FROM		titles ti,
		titleauthor ta,
		authors au,
		publishers pu
WHERE		ti.title_id = ta.title_id
AND		ta.au_id = au.au_id
AND		au.state = 'CA'
OR		ti.pub_id = pu.pub_id
AND		pu.state = 'CA'

Mi consulta es, yo pongo DISTINCT para que no me repita los resultados, pero en el fondo el rendimiento no se vería afectado? Tal vez aún no entiendo como funciona SQL internamente, a lo que voy es, al hacer esto, yo le estaría pidiendo a la Base de Datos 1000 registros pero sólo mostraría los que no se repiten? No sé si entienden a donde va mi duda. Se les ocurre otra manera de hacer la misma consulta pero de manera más eficiente o así está bien? Gracias!
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Duda sobre rendimiento de consulta

Publicado por Juan R. (12 intervenciones) el 10/11/2015 17:07:27
Buenas Walter

En cuanto a la manera de usar la consulta la menos eficiente siempre es el producto cartesiano, porque lo que se hace es combinar cada registro de la tabla A con cada uno de los registros de la tabla B, más allá del filtro aplicado en las condiciones del WHERE.

Esto produce la existencia de tablas virtuales (o derivadas) inmensas cargadas sin necesidad, que no pueden optimizarse porque las condiciones de optimización no están en la definición de la misma, sino en el WHERE.

En sustitución de lo anterior, el INNER/LEFT/RIGHT JOIN realiza un maching (búsqueda de coincidencias) entre las tablas en el momento de la lectura, haciendo la comparación sólo con los campos indicados en el ON, lo que redunda en lecturas mucho más reducidas y rápidas, que podrían ser optimizadas recurriendo a índices. Vamos que es mucho más eficiente usar los JOIN.

Si he entendido bien lo que quieres, libros publicados o publicados en 'California'. Yo haría una consulta principal con los libros publicados en California y a la vez una subconsulta con los que fueron escritos en otro sitio. Usando la claúsula DISTINC. No he probado la consulta y pueda tener algún error, pero mi propuesta sería algo más o menos similar a esto, si ves que tal has de adaptarlo:


libro

En esencia la consulta saca el título del libro en todos los libros que hayan sido publicados en 'California' (como ves uso el INNER JOIN aquí). Y la segunda condición del WHERE es que el title_id sea igual al title_id de todos los libros escritos en el mismo estado, esto se hace con otra subconsulta. Quizás te venga bien poner el DISTINC también en la subconsulta.

Como te he dicho es sólo una sugerencia y puede que no funcione al 100 %, pero te da un punto desde el que ir progresando, no?

Un saludo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar