Índices de MySQL y Optimización de Rendimiento

MySQLMySQLBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprenderá sobre los índices de MySQL y las técnicas de optimización de rendimiento. El laboratorio se centra en la creación y gestión de índices para mejorar el rendimiento de las consultas de la base de datos.

Comenzará creando una tabla users e insertando datos de muestra. Luego, creará un índice de una sola columna en la columna username y aprenderá cómo verificar su creación. El laboratorio también cubrirá el análisis de planes de consulta utilizando EXPLAIN, la adición de índices compuestos para consultas de múltiples columnas y la eliminación de índices no utilizados para mantener la eficiencia de la base de datos.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL mysql(("MySQL")) -.-> mysql/BasicKeywordsandStatementsGroup(["Basic Keywords and Statements"]) mysql(("MySQL")) -.-> mysql/AdvancedQueryingandOptimizationGroup(["Advanced Querying and Optimization"]) mysql(("MySQL")) -.-> mysql/SystemManagementToolsGroup(["System Management Tools"]) mysql/BasicKeywordsandStatementsGroup -.-> mysql/create_table("Table Creation") mysql/BasicKeywordsandStatementsGroup -.-> mysql/drop_table("Table Removal") mysql/BasicKeywordsandStatementsGroup -.-> mysql/alter_table("Table Modification") mysql/BasicKeywordsandStatementsGroup -.-> mysql/select("Data Retrieval") mysql/BasicKeywordsandStatementsGroup -.-> mysql/insert("Data Insertion") mysql/AdvancedQueryingandOptimizationGroup -.-> mysql/index("Index Management") mysql/SystemManagementToolsGroup -.-> mysql/show_status("Status Overview") subgraph Lab Skills mysql/create_table -.-> lab-550910{{"Índices de MySQL y Optimización de Rendimiento"}} mysql/drop_table -.-> lab-550910{{"Índices de MySQL y Optimización de Rendimiento"}} mysql/alter_table -.-> lab-550910{{"Índices de MySQL y Optimización de Rendimiento"}} mysql/select -.-> lab-550910{{"Índices de MySQL y Optimización de Rendimiento"}} mysql/insert -.-> lab-550910{{"Índices de MySQL y Optimización de Rendimiento"}} mysql/index -.-> lab-550910{{"Índices de MySQL y Optimización de Rendimiento"}} mysql/show_status -.-> lab-550910{{"Índices de MySQL y Optimización de Rendimiento"}} end

Crear un índice de una sola columna en una tabla

En este paso, aprenderá cómo crear un índice de una sola columna en MySQL. Los índices son cruciales para mejorar el rendimiento de las consultas de la base de datos, especialmente cuando se trabaja con tablas grandes. Un índice en una columna permite a la base de datos localizar rápidamente las filas que coinciden con un valor específico en esa columna, sin tener que escanear toda la tabla.

Comprender los índices

Piense en un índice como el índice de un libro. En lugar de leer todo el libro para encontrar un tema específico, puede usar el índice para localizar rápidamente las páginas relevantes. Del mismo modo, un índice de base de datos ayuda al motor de la base de datos a encontrar filas específicas rápidamente.

Crear una tabla

Primero, creemos una tabla simple llamada users para demostrar la creación de un índice. Abra una terminal en la máquina virtual (VM) de LabEx. Puede usar el acceso directo Xfce Terminal en el escritorio.

Conéctese al servidor MySQL como usuario root:

mysql -u root -proot

Ahora, cree la tabla users:

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Esta declaración SQL crea una tabla llamada users con columnas para id, username, email y created_at. La columna id se establece como clave primaria y se incrementa automáticamente.

Insertemos algunos datos de muestra en la tabla users:

INSERT INTO users (username, email) VALUES
('john_doe', '[email protected]'),
('jane_smith', '[email protected]'),
('peter_jones', '[email protected]');

Crear un índice de una sola columna

Ahora, creemos un índice en la columna username. Esto ayudará a acelerar las consultas que buscan usuarios por su nombre de usuario.

CREATE INDEX idx_username ON users (username);

Esta declaración crea un índice llamado idx_username en la columna username de la tabla users.

Verificar el índice

Puede verificar que se haya creado el índice utilizando el comando SHOW INDEXES:

SHOW INDEXES FROM users;

La salida mostrará los detalles de los índices en la tabla users, incluyendo el índice idx_username que acaba de crear. Debería ver una fila donde Key_name es idx_username y Column_name es username.

+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| users |          0 | PRIMARY      |            1 | id          | A         |           3 |     NULL | NULL   |      | BTREE      |         |               | YES     | NULL       |
| users |          1 | idx_username |            1 | username    | A         |           3 |     NULL | NULL   |      | BTREE      |         |               | YES     | NULL       |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+

Usar el índice

Para ver el beneficio del índice, puede usar el comando EXPLAIN para analizar una consulta que utiliza la columna username. Cubriremos EXPLAIN con más detalle en el siguiente paso, pero por ahora, veamos un ejemplo rápido.

EXPLAIN SELECT * FROM users WHERE username = 'john_doe';

La salida de EXPLAIN mostrará que la consulta está utilizando el índice idx_username, lo que significa que la base de datos puede encontrar rápidamente la fila coincidente sin escanear toda la tabla. Busque las columnas possible_keys y key en la salida. Si se está utilizando el índice, verá idx_username en estas columnas.

Ahora ha creado con éxito un índice de una sola columna en una tabla. Esto mejorará el rendimiento de las consultas que filtran datos en función de la columna indexada.

exit;

Analizar un plan de consulta utilizando EXPLAIN

En este paso, aprenderá cómo utilizar la declaración EXPLAIN en MySQL para analizar el plan de ejecución de una consulta. Comprender el plan de consulta es esencial para identificar cuellos de botella de rendimiento y optimizar sus consultas.

¿Qué es un plan de consulta?

Un plan de consulta es una hoja de ruta que el motor de la base de datos utiliza para ejecutar una consulta. Describe el orden en el que se acceden a las tablas, los índices que se utilizan y los algoritmos que se aplican para recuperar los datos. Al analizar el plan de consulta, puede entender cómo la base de datos está ejecutando su consulta e identificar áreas de mejora.

Utilizar la declaración EXPLAIN

La declaración EXPLAIN proporciona información sobre cómo MySQL ejecuta una consulta. Muestra las tablas involucradas, los índices utilizados, el orden de unión y otros detalles que pueden ayudarlo a entender el rendimiento de la consulta.

Continuemos utilizando la tabla users que creamos en el paso anterior. Abra una terminal en la máquina virtual (VM) de LabEx (utilizando el acceso directo Xfce Terminal en el escritorio) y conéctese al servidor MySQL como usuario root:

mysql -u root -proot

Ahora, analicemos una consulta simple utilizando EXPLAIN.

EXPLAIN SELECT * FROM users WHERE username = 'john_doe';

La salida de la declaración EXPLAIN será una tabla con varias columnas. Aquí está un desglose de algunas de las columnas más importantes:

  • id: El ID de la declaración SELECT.
  • select_type: El tipo de consulta SELECT (por ejemplo, SIMPLE, PRIMARY, SUBQUERY).
  • table: La tabla a la que se accede.
  • type: El tipo de unión. Esta es una de las columnas más importantes. Los valores comunes incluyen:
    • system: La tabla tiene solo una fila.
    • const: La tabla tiene como máximo una fila coincidente, que se lee al comienzo de la consulta.
    • eq_ref: Se lee una fila de esta tabla para cada combinación de filas de las tablas anteriores. Esto se utiliza cuando se realiza una unión en una columna indexada.
    • ref: Se leen todas las filas coincidentes de esta tabla para cada combinación de filas de las tablas anteriores. Esto se utiliza cuando se realiza una unión en una columna indexada.
    • range: Solo se recuperan las filas dentro de un rango dado, utilizando un índice.
    • index: Se realiza un examen completo del índice.
    • ALL: Se realiza un examen completo de la tabla. Este es el tipo menos eficiente.
  • possible_keys: Los índices que MySQL podría utilizar para encontrar las filas en la tabla.
  • key: El índice que MySQL realmente utilizó.
  • key_len: La longitud de la clave que MySQL utilizó.
  • ref: Las columnas o constantes que se comparan con el índice.
  • rows: El número de filas que MySQL estima que tendrá que examinar para ejecutar la consulta.
  • Extra: Información adicional sobre cómo MySQL está ejecutando la consulta. Los valores comunes incluyen:
    • Using index: La consulta se puede satisfacer utilizando solo el índice.
    • Using where: MySQL necesita filtrar las filas después de acceder a la tabla.
    • Using temporary: MySQL necesita crear una tabla temporal para ejecutar la consulta.
    • Using filesort: MySQL necesita ordenar las filas después de acceder a la tabla.

Interpretar la salida de EXPLAIN

Para la consulta SELECT * FROM users WHERE username = 'john_doe', la salida de EXPLAIN debería verse algo así:

+----+-------------+-------+------------+------+---------------+--------------+---------+-------+------+-------+-------+
| id | select_type | table | partitions | type | possible_keys | key          | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+--------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | users | NULL       | ref  | idx_username  | idx_username | 767     | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+--------------+---------+-------+------+----------+-------+

En este ejemplo:

  • type es ref, lo que significa que MySQL está utilizando un índice para encontrar la fila coincidente.
  • possible_keys y key muestran idx_username, lo que significa que MySQL está utilizando el índice idx_username que creamos en el paso anterior.
  • rows es 1, lo que significa que MySQL estima que tendrá que examinar solo una fila para ejecutar la consulta.

Analizar una consulta sin un índice

Ahora, analicemos una consulta que no utiliza un índice. Primero, agreguemos una nueva columna a la tabla users llamada city:

ALTER TABLE users ADD COLUMN city VARCHAR(255);

Ahora, ejecutemos un EXPLAIN en una consulta que busca por city:

EXPLAIN SELECT * FROM users WHERE city = 'New York';

Como no hemos agregado ningún dato a la columna city, actualicemos una de las filas:

UPDATE users SET city = 'New York' WHERE username = 'john_doe';

Ahora, ejecute la declaración EXPLAIN nuevamente:

EXPLAIN SELECT * FROM users WHERE city = 'New York';

La salida podría verse así:

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | users | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |    33.33 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+

En este ejemplo:

  • type es ALL, lo que significa que MySQL está realizando un examen completo de la tabla.
  • possible_keys y key son NULL, lo que significa que MySQL no está utilizando ningún índice.
  • rows es 3, lo que significa que MySQL estima que tendrá que examinar todas las 3 filas de la tabla para ejecutar la consulta.
  • Extra muestra Using where, lo que significa que MySQL necesita filtrar las filas después de acceder a la tabla.

Esto indica que la consulta no está optimizada y podría beneficiarse de un índice en la columna city.

exit;

Agregar un índice compuesto para consultas de múltiples columnas

En este paso, aprenderá cómo crear un índice compuesto en MySQL. Un índice compuesto es un índice en dos o más columnas de una tabla. Puede mejorar significativamente el rendimiento de las consultas que filtran datos en función de múltiples columnas.

¿Qué es un índice compuesto?

Un índice compuesto es un índice que abarca múltiples columnas. Es útil cuando las consultas utilizan con frecuencia múltiples columnas en la cláusula WHERE. El orden de las columnas en el índice compuesto es importante. El índice es más efectivo cuando las columnas se especifican en el mismo orden en la cláusula WHERE de la consulta.

Continuemos utilizando la tabla users que creamos en los pasos anteriores. Abra una terminal en la máquina virtual (VM) de LabEx (utilizando el acceso directo Xfce Terminal en el escritorio) y conéctese al servidor MySQL como usuario root:

mysql -u root -proot

Agreguemos más datos a la tabla users, incluyendo diferentes ciudades:

INSERT INTO users (username, email, city) VALUES
('alice_brown', '[email protected]', 'Los Angeles'),
('bob_davis', '[email protected]', 'Chicago'),
('charlie_wilson', '[email protected]', 'New York'),
('david_garcia', '[email protected]', 'Los Angeles');

Crear un índice compuesto

Supongamos que a menudo ejecuta consultas que filtran usuarios por city y username. En este caso, puede crear un índice compuesto en las columnas city y username.

CREATE INDEX idx_city_username ON users (city, username);

Esta declaración crea un índice llamado idx_city_username en las columnas city y username de la tabla users.

Verificar el índice

Puede verificar que se haya creado el índice utilizando el comando SHOW INDEXES:

SHOW INDEXES FROM users;

La salida mostrará los detalles de los índices en la tabla users, incluyendo el índice idx_city_username que acaba de crear. Debería ver dos filas para idx_city_username, una para la columna city y otra para la columna username.

+-------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name          | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| users |          0 | PRIMARY           |            1 | id          | A         |           7 |     NULL | NULL   |      | BTREE      |         |               | YES     | NULL       |
| users |          1 | idx_username      |            1 | username    | A         |           7 |     NULL | NULL   |      | BTREE      |         |               | YES     | NULL       |
| users |          1 | idx_city_username |            1 | city        | A         |           3 |     NULL | NULL   | YES  | BTREE      |         |               | YES     | NULL       |
| users |          1 | idx_city_username |            2 | username    | A         |           7 |     NULL | NULL   |      | BTREE      |         |               | YES     | NULL       |
+-------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+

Utilizar el índice compuesto

Para ver el beneficio del índice compuesto, puede utilizar el comando EXPLAIN para analizar una consulta que utiliza tanto la columna city como la columna username en la cláusula WHERE.

EXPLAIN SELECT * FROM users WHERE city = 'New York' AND username = 'charlie_wilson';

La salida de EXPLAIN mostrará que la consulta está utilizando el índice idx_city_username, lo que significa que la base de datos puede encontrar rápidamente la fila coincidente sin escanear toda la tabla. Busque las columnas possible_keys y key en la salida. Si se está utilizando el índice, verá idx_city_username en estas columnas.

+----+-------------+-------+------------+------+-------------------+-------------------+---------+-------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys     | key               | key_len | ref         | rows | filtered | Extra |
+----+-------------+-------+------------+------+-------------------+-------------------+---------+-------------+------+----------+-------+
|  1 | SIMPLE      | users | NULL       | ref  | idx_city_username | idx_city_username | 770     | const,const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+-------------------+-------------------+---------+-------------+------+----------+-------+

Orden de las columnas en el índice

El orden de las columnas en el índice compuesto es importante. Si crea un índice en (username, city) en lugar de (city, username), el índice será menos efectivo para las consultas que filtran por city y luego por username.

Por ejemplo, si tuviéramos un índice en (username, city) y ejecutáramos la siguiente consulta:

EXPLAIN SELECT * FROM users WHERE city = 'New York' AND username = 'charlie_wilson';

MySQL podría no utilizar el índice, o podría utilizarlo solo parcialmente, porque la columna city no es la columna principal en el índice.

exit;

Eliminar un índice no utilizado

En este paso, aprenderá cómo eliminar un índice no utilizado en MySQL. Si bien los índices pueden mejorar significativamente el rendimiento de las consultas, también agregan sobrecarga a las operaciones de escritura (inserciones, actualizaciones y eliminaciones). Por lo tanto, es importante identificar y eliminar los índices que ya no se utilizan.

¿Por qué eliminar índices no utilizados?

Los índices no utilizados ocupan espacio en el disco y pueden ralentizar las operaciones de escritura. Cuando se modifican los datos en una tabla, el motor de la base de datos también debe actualizar todos los índices de esa tabla. Si un índice no se utiliza en ninguna consulta, solo está agregando una sobrecarga innecesaria.

Continuemos utilizando la tabla users que creamos en los pasos anteriores. Abra una terminal en la máquina virtual (VM) de LabEx (utilizando el acceso directo Xfce Terminal en el escritorio) y conéctese al servidor MySQL como usuario root:

mysql -u root -proot

En los pasos anteriores, creamos un índice llamado idx_username en la columna username. Supongamos que, después de analizar sus patrones de consulta, determina que este índice ya no se utiliza.

Eliminar el índice

Para eliminar el índice idx_username, puede utilizar la declaración DROP INDEX:

DROP INDEX idx_username ON users;

Esta declaración elimina el índice idx_username de la tabla users.

Verificar la eliminación del índice

Puede verificar que el índice se haya eliminado utilizando el comando SHOW INDEXES:

SHOW INDEXES FROM users;

La salida mostrará los detalles de los índices en la tabla users. Ya no debería ver el índice idx_username en la salida.

+-------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name          | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| users |          0 | PRIMARY           |            1 | id          | A         |           7 |     NULL | NULL   |      | BTREE      |         |               | YES     | NULL       |
| users |          1 | idx_city_username |            1 | city        | A         |           3 |     NULL | NULL   | YES  | BTREE      |         |               | YES     | NULL       |
| users |          1 | idx_city_username |            2 | username    | A         |           7 |     NULL | NULL   |      | BTREE      |         |               | YES     | NULL       |
+-------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+

Identificar índices no utilizados

En un escenario del mundo real, identificar los índices no utilizados puede ser un desafío. MySQL proporciona varias herramientas y técnicas para ayudarlo con esta tarea:

  • MySQL Enterprise Audit: Esta función le permite registrar todas las consultas ejecutadas en su servidor. Luego, puede analizar los registros de consultas para identificar qué índices se están utilizando.
  • Performance Schema: El Performance Schema proporciona información detallada sobre el rendimiento del servidor, incluyendo el uso de índices.
  • Herramientas de terceros: Varias herramientas de terceros pueden ayudarlo a monitorear el uso de índices e identificar los índices no utilizados.

Al monitorear regularmente el uso de sus índices y eliminar los índices no utilizados, puede mejorar el rendimiento general de su base de datos.

exit;

Resumen

En este laboratorio, aprendiste cómo crear un índice de una sola columna en MySQL para mejorar el rendimiento de las consultas, especialmente en tablas grandes. El proceso incluyó conectarse al servidor de MySQL, crear una tabla users con columnas para id, username, email y created_at, e insertar datos de muestra.

El paso clave fue crear un índice llamado idx_username en la columna username utilizando la declaración CREATE INDEX. Este índice acelerará las consultas que buscan usuarios por su nombre de usuario, lo que permite a la base de datos localizar rápidamente las filas que coinciden con valores específicos de nombre de usuario sin escanear toda la tabla.