Está en la página 1de 18

PRÁCTICA 7: ÍNDICES 

 
04-02-2021 

Pedro Ferreiro Mendoza 


Pedro Ferreiro Mendoza   2ASIR   20/21

 
ÍNDICE DE CONTENIDOS: 

TAREA 1 3 

TAREA 2 3 

TAREA 3 4 

TAREA 4 5 

TAREA 5 9 
TAREA 6 11 

TAREA 7 11 

TAREA 8 13 

TAREA 9 14 

 
 
 
 
 
 
 
 
 
 
 
 

Pedro Ferreiro Mendoza 2


Pedro Ferreiro Mendoza   2ASIR   20/21

TAREA 1 
Instalación de la base de datos employees en nuestro servidor MySQL. 
 
Ejecutamos el siguiente comando para extraer la base de datos. 

 
Y tecleamos el siguiente comando. 

TAREA 2 
Instalación de la base de datos sakila en nuestro servidor MySQL. 
 
Ya está instalado. 
 
 
EXPLAIN 
 
key_len  funciona el índice. 
possible key  El índice que puede usar.  
key Índice a usar. 
extra  Si es costosa o no 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Pedro Ferreiro Mendoza 3


Pedro Ferreiro Mendoza   2ASIR   20/21

TAREA 3 
Recupera la información relativa a los índices que hay en la tablas employees, 
dept_emp y salaries de la base de datos employees, y rellena la siguiente tabla. Pon 
algún ejemplo de consulta SQL que se pueda resolver utilizando dichos índices, 
comprobando que efectivamente, así es. 
 
SELECT table_name,engine from information_schema.tables WHERE table_schema='employees'; 
SHOW INDEX FROM tabla FROM employees; 
 
Dato  Tabla  Tabla Salaries  Tabla  Tabla 
Employees  PRIMARY  dept_emp  dept_emp 
PRIMARY  PRIMARY  Dept_no 

Motor de  InnoDB  InnoDB  InnoDB  InnoDB 


almacenamien
to 

Estructura de  BTREE  BTREE  BTREE  BTREE 


índice (BTREE, 
HASH,…) 

Columnas del  emp_no  from_date,emp_ dept_no, emp_no  dept_no 


índice  no 

Es único?  0  0  0  1 

Cardinalidad  299379  2606794  331143  8 


277146  299636 

Visibilidad del  Yes  Yes  Yes  Yes 


índice 
 
 
 
 
 
 
 
 
 
 

Pedro Ferreiro Mendoza 4


Pedro Ferreiro Mendoza   2ASIR   20/21

TAREA 4 
Supongamos que en la tabla employees creamos el índice (last_name, first_name). 
Analiza si las siguientes consultas utilizarán dicho índice, justificando la respuesta. 
Indica si crees que el optimizador todavía realiza alguna operación demasiado 
“costosa” para resolver la consulta, a pesar de usar índices, y cómo podría mejorar o 
evitar dicha operación. 
 
Primero vamos a crear el índice: 

 
 
1. SELECT last_name, first_name, hire_date FROM employees WHERE last_name 
='Marchesini'; 
 
Gracias a que el índice está ordenado primero last_name y después first_name favorece a la 
búsqueda, por lo tanto ​si utiliza el índice​. 

 
 
2. SELECT last_name, first_name, hire_date FROM employees WHERE first_name 
='Claude'; 
 
La consulta ​no hará uso de índice​, ya que no lleva el mismo orden con el cual se ha establecido el 
índice (por el valor más a la izquierda). 

 
 
 
 
 
 
 

Pedro Ferreiro Mendoza 5


Pedro Ferreiro Mendoza   2ASIR   20/21

3. SELECT last_name, first_name, emp_no FROM employees WHERE last_name LIKE 


'A%'; 
 
Si​ ​hace​ ​uso de índice​ ya que facilita la búsqueda en un rango o que cumplan un determinado 
patrón, y además está ordenado. 

 
4. SELECT last_name, first_name, emp_no FROM employees WHERE last_name LIKE 
'A%' AND first_name LIKE 'F%'; 
 
Si hace uso de índice​, ya que lleva el orden establecido en el índice (por el prefijo más a la 
izquierda) y además busca en un rango. 

 
5. SELECT last_name, first_name, hire_date FROM employees WHERE last_name LIKE 
'A%' AND first_name LIKE 'F%'; 
 
Si hace uso de índice​, ya que lleva el orden establecido en el índice (por el prefijo más a la 
izquierda) y busca en rango de forma ordenada. 

 
6. SELECT last_name, first_name, hire_date FROM employees WHERE last_name LIKE 
'A%' AND first_name LIKE 'F%' ORDER BY last_name; 
 
Si hace uso de índice, ​como anteriormente ​lleva el orden establecido en el índice (por el prefijo 
más a la izquierda) y busca en rango ordenado, además también es útil ya que ordena por ambos 
campos, y la ordenación por last_name no supone ninguna operación adicional. 

 
 
 

Pedro Ferreiro Mendoza 6


Pedro Ferreiro Mendoza   2ASIR   20/21

7. SELECT last_name, first_name, hire_date FROM employees WHERE last_name LIKE 


'A%' AND first_name LIKE 'F%' ORDER BY first_name; 
 
Si hace uso de índice,​ como anteriormente lleva el orden establecido en el índice (por el prefijo 
más a la izquierda) y busca en rango ordenado, y además también es útil ya que ordena por ambos 
campos, pero esto provoca una operación costosa ya que no se indica el orden (ASC o DESC), para 
evitar realizar la costosa operación “filesort”. 

 
 
8. SELECT last_name, first_name, hire_date FROM employees WHERE last_name LIKE 
'A%' AND first_name LIKE 'F%' ORDER BY last_name, first_name, emp_no; 
 
Si hace uso de índice​, lleva el orden establecido en el índice (por el prefijo más a la izquierda) y 
busca en rango ordenado por ambos valores, además también es útil ya que ordena por ambos 
campos. 

 
 
9. SELECT last_name, first_name FROM employees ORDER BY last_name, first_name 
DESC  
 
Si hace uso de índice, ​este también está ordenando como indica el índice (por el prefijo más a la 
izquierda) y utiliza el order by para ordenar ambos valores sin cláusula where , pero esto provoca 
una operación costosa ya que no se indica el orden (ASC o DESC), para evitar realizar la costosa 
operación “filesort”. 

 
 
 
 
 
 
 

Pedro Ferreiro Mendoza 7


Pedro Ferreiro Mendoza   2ASIR   20/21

10. SELECT last_name, first_name FROM employees ORDER BY last_name, first_name 


 
Si hace uso de índice​, lleva el orden establecido en el índice (por el prefijo más a la izquierda) y 
utiliza el order by para ordenar ambos valores sin cláusula where. 

 
 
11. SELECT last_name, first_name, gender FROM employees ORDER BY last_name, 
first_name DESC 
 
No hace uso de índice​, si está ordenado por lo establecido en el índice (por el prefijo más a la 
izquierda) pero utiliza el order by de forma descendiente en una consulta la cual se va a indicar el 
género es decir que solo puede haber dos tipos. 

 
 
12. SELECT last_name, first_name, MAX(salary) FROM employees INNER JOIN salaries 
ON employees.emp_no=salaries.emp_no GROUP BY last_name, first_name 
 
Si hace uso de índice, ​con el inner join hace que se una la clave primaria de una tabla con la clave 
ajena de la otra por lo tanto con el índice se optimiza, pero se podría optimizar aún más haciendo un 
índice en el cual se uniera salary.  

Pedro Ferreiro Mendoza 8


Pedro Ferreiro Mendoza   2ASIR   20/21

TAREA 5 
Determina los índices que tendrás que crear (si no existiesen) para mejorar la 
resolución de las siguientes consultas, razonando la respuesta. 
 
1. SELECT distinct title FROM titles ORDER BY title DESC 
 
No es necesario indice para esta consulta ya que tiene un índice PRIMARY asociado. 

 
2. SELECT last_name, first_name FROM employees WHERE emp_no IN (SELECT 
DISTINCT emp_no FROM titles WHERE title IN ('Engineer')) 

 
Hace uso del índice indicado en otros ejercicios, esto es porque title tiene valores repetidos por lo 
que sí se puede optimizar. 

 
3. SELECT emp_no, MAX(salary) FROM salaries GROUP BY emp_no ORDER BY 
MAX(salary) DESC; 
 

 
Se podría crear un índice formado por (emp_no, salary), ya que las funciones MAX y MIN pueden ser 
optimizados también mediante índices. 

 
 
 
 
 

Pedro Ferreiro Mendoza 9


Pedro Ferreiro Mendoza   2ASIR   20/21

4. SELECT last_name, first_name, title FROM employees INNER JOIN titles ON 
employees.emp_no=titles.emp_no WHERE title LIKE 'Senior%' ORDER BY title 

 
Ya hay varios índices creados en la columna emp_no en ambas tablas employees y titles, pero se 
podría crear un índice sobre la columna (title) de la tabla titles. 

 
 
5. SELECT emp_no, hire_date FROM employees WHERE emp_no IN (SELECT DISTINCT 
emp_no FROM dept_emp WHERE dept_no=(SELECT dept_no FROM departments 
WHERE dept_name='Marketing')) ORDER BY hire_date DESC LIMIT 1 
 
No se puede crear indice de la siguiente consulta, ya que si vamos mirando en cada select interno 
podemos ver que el primero no tiene las suficientes filas como para que se pueda escribir un índice, 
en el segundo ya existe un índice para dept_no y para el select de la tabla employees no utilizara el 
índice ya habría que optimizarla. 

 
 
 
 
 
 
 
 
 
 

Pedro Ferreiro Mendoza 10


Pedro Ferreiro Mendoza   2ASIR   20/21

TAREA 6
Crea el índice (gender, hire_date) en la tabla employees. Haz que la siguiente consulta 
lo utilice:  
 
SELECT * FROM employees WHERE hire_date BETWEEN '1985-10-07' AND '1985-10-10'  
 
Primero vamos a crear el índice: 

 
 
Modificamos la consulta para que utilice el índice, lo único que añadimos es una condición con el 
género que será ​IN ​y eliminamos el ​BETWEEN​ por un ​IN​. 
 
SELECT * FROM employees WHERE gender IN ('M', 'F') AND hire_date IN ('1985-10-07', '1985-10-08', 
'1985-10-09' ,'1985-10-10');’  

 
 
 

TAREA 7 
Reescribe las siguientes consultas de la base de datos sakila para una más rápida 
ejecución. Si no existiesen, crea los índices más adecuados que correspondan, según 
el tipo de datos de los campos. 
 
Creamos el índice oportuno para este ejercicio, esto nos permitirá optimizar 
las búsquedas en los campos de texto. 

 
 
 
 
 
 
 

Pedro Ferreiro Mendoza 11


Pedro Ferreiro Mendoza   2ASIR   20/21

1. SELECT title FROM film WHERE description LIKE '%China%'  


Modificamos la consulta para que el índice FULLTEXT pueda ser utilizado ya que este solo realiza 
búsquedas con la cláusula ​MATCH-AGAINST​. 
 
SELECT title FROM film WHERE MATCH (description) AGAINST ("China"); 

 
 
2. SELECT title FROM film WHERE description LIKE '%Teacher%' OR description LIKE 
'%China%'  
Como anteriormente vamos a modificar la consulta para utilizar el índice, en esta consulta vamos a 
buscar una de las palabras o todas, Teacher o China. 
 
SELECT title FROM film WHERE MATCH (description) AGAINST ("Teacher China"); 

 
3. SELECT title FROM film WHERE description LIKE '%Teacher%' AND description LIKE 
'%China%' 
 
Ahora deberemos de modificar la consulta para que aparezcan las dos palabras en la misma 
descripción, para ello utilizamos el ​+​ (indica que la palabra debe estar presente en cada resultado) 
más el ​IN BOOLEAN MOD​E (ofrece operadores que puedes utilizar para indicar el tratamiento de las 
palabras) . 
 
SELECT title FROM film WHERE MATCH (description) AGAINST ("+Teacher +China" IN BOOLEAN 
MODE); 

 
 
 

Pedro Ferreiro Mendoza 12


Pedro Ferreiro Mendoza   2ASIR   20/21

TAREA 8 
Considera las siguientes consultas sobre la BD Sakila:  
1. SELECT * FROM film WHERE rating='G' OR rating='PG';  
Creamos el índice: 

 
Para optimizar la consulta al llevar OR no se optimizan bien con índices, salvo que las 
reescribamos mediante UNION. 
SELECT * FROM film WHERE rating=’G’ UNION DISTINCT SELECT * FROM film WHERE rating=’PG’ 

 
2. SELECT * FROM film WHERE rental_duration BETWEEN 4 AND 6 AND 
release_year=2006;  
Creamos el índice para este apartado: 

 
 
Para optimizar esta consulta y que utilice el índice deberemos de añadir varios UNION, que nos 
permite seleccionar los valores del 4 al 6 y en cada UNION deberá ir el AND de release_year para no 
obtener ningún error. 
 
SELECT * FROM film WHERE rental_duration='4' AND release_year=2006 UNION DISTINCT SELECT * 
FROM film WHERE rental_duration='5' AND release_year=2006 UNION DISTINCT SELECT * FROM 
film WHERE rental_duration='6' AND release_year=2006; 
 

 
 
 

Pedro Ferreiro Mendoza 13


Pedro Ferreiro Mendoza   2ASIR   20/21

TAREA 9 

Apartado 1

Crear una tabla “empleados” en la BD employees, que sea una copia exacta de la tabla 
employees (estructura y datos, no índices), pero usando el motor de almacenamiento 
MEMORY.  
 
Creamos la tabla empleados:  

 
Ahora vamos a añadir los datos por medio de un INSERT INTO con un SELECT (este seleccionara 
todos los datos de la tabla employees).  

Apartado 2  

¿Qué ocurre con la tabla “empleados” si ahora reinicias el servidor MySQL?  


Vemos que hay datos en la tabla empleados. 

 
Vamos a reiniciar el servicio, para ver lo que ocurre. 

Pedro Ferreiro Mendoza 14


Pedro Ferreiro Mendoza   2ASIR   20/21

Al reiniciar el servicio no hay datos debido a que MEMORY crea tablas con contenidos que se 
almacenan en memoria. 

Apartado 3  
Crea un índice HASH para los atributos (last_name, first_name) de la tabla “empleados”. 
Verifica que el índice se ha creado en la tabla INFORMATION_SCHEMA.STATISTICS.  

 
Mediante esta consulta recuperamos todos los índices de la base de datos employees y las 
columnas que incluye cada índice. 

Pedro Ferreiro Mendoza 15


Pedro Ferreiro Mendoza   2ASIR   20/21

Apartado 4  

Comprueba que el índice creado es utilizado en la ejecución de la consulta SELECT * FROM 


empleados WHERE last_name='Tsukuda' AND first_name='Sachin' . 
Si hace uso de la consulta, esto es porque las consultas HASH solo se usan cuando se buscan 
valores en igualdad con los operadores =, IN() y <=>. 

Apartado 5  

Crea una consulta SQL que no use el índice creado en el apartado.  


 
Simplemente hacemos una consulta la cual no lleva ninguno de estos operadores ​=, IN() y <=>​ , por 
lo que hago una consulta con​ LIKE​ y el índice ya no es utilizado. 
 
SELECT * FROM empleados WHERE last_name LIKE 'T%' AND first_name LIKE 'S%'; 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Pedro Ferreiro Mendoza 16


Pedro Ferreiro Mendoza   2ASIR   20/21

Apartado 6  

Ejecuta las consultas de los apartados 4 y 5 contra la tabla original employees, y compara 
tiempos de ejecución frente a los obtenidos con la tabla empleados. 
 
Tabla empleados 
- Ejercicio 4 
La consulta tiene un tiempo de ejecución muy rápido, tanto que no llega ni a 0.01 segundos. 

 
Tabla employees 
- Ejercicio 4 
La consulta en la tabla employees tarda ​0.01 segundos​ más, esto es debido al motor de 
almacenamiento que tiene la tabla empleados, ya que todos los datos los almacena en la memoria. 

 
 
Tabla empleados 
- Ejercicio 5 
La consulta en la tabla empleados aun no teniendo índice tarda tan solo 0.06 segundos. 

 
 
 
 
 

Pedro Ferreiro Mendoza 17


Pedro Ferreiro Mendoza   2ASIR   20/21

Tabla employees 
- Ejercicio 5 
La consulta en esta tabla tarda 0,67 segundos. 

Pedro Ferreiro Mendoza 18

También podría gustarte