Preguntas para la práctica 4 Código de grupo: Nombre y apellidos: Nombre y apellidos: 1 Excribir una instrucción explain plan para la consulta que devuelve todos los destinos a los que viaja el pasajero con nombre Crescencio. El STATEMENT_ID será 'Destinos Crescencio' . Solución: explain plan SET STATEMENT_ID = 'Destinos Crescencio' INTO Planes for select destino from tpasajeros,tvuelos where tvuelos.id=tpasajeros.vuelo and tpasajeros.nombre='Crescencio' ; 2 Ver por pantalla los datos del plan anterior. Entre ellos aparece una opción “Range Scan” ¿A qué atributo se refiere? ¿qué significa? Solución: SELECT operation, options, object_name FROM planes where statement_id = 'Destinos Crescencio' START with id = 0 connect by prior id=parent_id and prior statement_id = statement_id; Muestra: OPERATION -----------------------------SELECT STATEMENT NESTED LOOPS INDEX TABLE ACCESS INDEX OPTIONS --------------- - OBJECT_NAME ------------------- RANGE SCAN BY INDEX ROWID UNIQUE SCAN SYS_C0098603 TVUELOS SYS_C0098601 El primer index con « Range Scan » se refiere a que el índice asociado a la clave de tpasajeros se puede utilizar para sacar todos los pasajeros que se llaman Crescencio, pero que puede haber varios ya que el nombre no es clave. Es decir 1º se seleccionan todos los pasajeros de nombre Crescencio y a continuación se busca su vuelo en vuelos usando el índice asociado a la clave. 3 Crea el índice para la columna tipoavion de tvuelos. Copia aquí la instrucción utilizada con este propósito. Solución: create index ivuelos_tipoavion on tvuelos(tipoavion); 4 Escribe una consulta para saber que tipos de avión de los que se encuentran en taviones no realizan ningún vuelo. La consulta debe usar not exists Copia aquí la consulta, el plan y explica éste último. Solución: Instrucción: select tipo from taviones where not exists (select * from tvuelos where tipo=tipoavion); Plan: OPERATION OPTIONS OBJECT_NAME ------------------------------ --------------- -------------------SELECT STATEMENT FILTER TABLE ACCESS FULL TAVIONES INDEX RANGE SCAN IVUELOS_TIPOAVION SQL decide que tiene que recorrer una tabla al completo y buscar en la otra. Es interesante observar que no se puede hacer (mucho) mejor: no tendría sentido utilizar los dos índices, porque una de las dos tablas va a ser recorrida completamente en cualquier caso. 5 Repetir la consulta anterior pero ahora rescribiéndola con not int en lugar de con not exists. Escribir el plan correspondiente ¿Qué es más eficiente, not exists o not in? Instrucción incluida en la creación del plan: SELECT operation, options, object_name FROM planes where statement_id = 'faltan' START with id = 0 connect by prior id=parent_id and prior statement_id = statement_id; OPERATION OPTIONS OBJECT_NAME ------------------------------ --------------- -------------------SELECT STATEMENT FILTER TABLE ACCESS TABLE ACCESS FULL FULL TAVIONES TVUELOS ¡Ahora se recorren las dos tablas por completo! Es mucho más eficiente not exists y debe ser preferido a not in siempre que sea posible. 6 Muestra el plan para la consulta select * from tvuelos where upper(tipoAvion) = upper('Boeing 707'); y trata de explicar qué pasa. Solución: OPERATION OPTIONS OBJECT_NAME ------------------------------ --------------- -------------------SELECT STATEMENT TABLE ACCESS FULL TVUELOS No se usa el índice porque la función upper lo impide. 7 Muestra y explica el plan para: update tvuelos set pasajeros=pasajeros+1 where id='IBE 398' and pasajeros<(select capacidad from taviones where taviones.tipo=tvuelos.tipoavion); Solución OPERATION -----------------------------UPDATE STATEMENT UPDATE FILTER TABLE ACCESS INDEX TABLE ACCESS INDEX OPTIONS --------------- OBJECT_NAME ------------------TVUELOS BY INDEX ROWID UNIQUE SCAN BY INDEX ROWID UNIQUE SCAN TVUELOS SYS_C0098601 TAVIONES SYS_C0098600 En ambos casos se usa el índice creado por Oracle de forma automática.