sql >> Base de Datos >  >> RDS >> Mysql

El índice Mysql a la vista no funciona

No puede crear un índice en una vista:http:/ /dev.mysql.com/doc/refman/5.7/en/view-restrictions.html , por lo que debe esperar que se use el índice. https://stackoverflow.com/a/7922711/3595565

Solución alternativa

Hay una solución mencionada en los comentarios de otra parte de la documentación:https://dev.mysql.com/doc/refman/5.5/en/create-view.html En el que crea una tabla normal y establece su índice especializado y carga los datos de la vista en la tabla.

LOCK TABLES materializedView WRITE; 
TRUNCATE materializedView; 
INSERT INTO materializedView SELECT * FROM regularView;
UNLOCK TABLES;

¿Por qué su consulta no utiliza los índices?

Al usar UNION en un SELECT mysql crea una tabla temporal para guardar los datos. Por lo tanto, como una vista es un 'atajo' para su consulta más compleja, al llamar a la selección, volverá a ejecutar la unión, usará una tabla temporal... usará el algoritmo tentable para procesar los datos.

Revisando el manual nuevamente:http://dev.mysql. com/doc/refman/5.7/en/view-restrictions.html

Conclusión :La UNION en su consulta impide que la vista use los índices.

Fuentes

pregunta en el foro mysql por el mismo problema respuesta:

bugreport "NO CREAR TABLAS TEMPORALES PARA UNIR TODOS"

Corregido en MySQL 5.7 http:/ /dev.mysql.com/doc/relnotes/mysql/5.7/en/noticias-5-7-3.html

Algunos datos de prueba para comprobar el generador de perfiles

CREATE TABLE test1 (
    id int auto_increment PRIMARY KEY,
  col1 varchar(50),
  col2 varchar(50)
);

CREATE TABLE test2 (
    id int auto_increment PRIMARY KEY,
  col1 varchar(50),
  col2 varchar(50)
);

INSERT INTO test1 (col1, col2) 
VALUES 
('test', 'testcol2'),
('test', 'testcol2'),
('test', 'testcol2'),
('test', 'testcol2'),
('test', 'testcol2'),
('test', 'testcol2');


INSERT INTO test2 (col1, col2) 
VALUES 
('test2', 'testcol2'),
('test2', 'testcol2'),
('test2', 'testcol2'),
('test2', 'testcol2'),
('test2', 'testcol2'),
('test2', 'testcol2');

CREATE VIEW testview AS
SELECT * FROM test1
UNION
SELECT * FROM test2;

Revisa el generador de perfiles:

SET PROFILING = 1;
SELECT * FROM testview WHERE id = 1;
+----+-------+----------+
| id | col1  | col2     |
+----+-------+----------+
|  1 | test  | testcol2 |
|  1 | test2 | testcol2 |
+----+-------+----------+
SHOW PROFILE;
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| starting                       | 0.000017 |
| Waiting for query cache lock   | 0.000004 |
| checking query cache for query | 0.000029 |
| checking permissions           | 0.000006 |
| Opening tables                 | 0.000121 |
| System lock                    | 0.000012 |
| checking permissions           | 0.000014 |
| checking permissions           | 0.000032 |
| optimizing                     | 0.000004 |
| statistics                     | 0.000007 |
| preparing                      | 0.000006 |
| executing                      | 0.000003 |
| Sending data                   | 0.000046 |
| optimizing                     | 0.000003 |
| statistics                     | 0.000004 |
| preparing                      | 0.000003 |
| executing                      | 0.000002 |
| Sending data                   | 0.000023 |
| optimizing                     | 0.000003 |
| statistics                     | 0.000003 |
| preparing                      | 0.000003 |
| executing                      | 0.000002 |
| Sending data                   | 0.000008 |
| removing tmp table             | 0.000005 |
| Sending data                   | 0.000005 |
| Waiting for query cache lock   | 0.000002 |
| Sending data                   | 0.000024 |
| init                           | 0.000011 |
| optimizing                     | 0.000006 |
| statistics                     | 0.000004 |
| preparing                      | 0.000006 |
| executing                      | 0.000002 |
| Sending data                   | 0.000021 |
| end                            | 0.000003 |
| query end                      | 0.000004 |
| closing tables                 | 0.000002 |
| removing tmp table             | 0.000004 |
| closing tables                 | 0.000006 |
| freeing items                  | 0.000005 |
| Waiting for query cache lock   | 0.000003 |
| freeing items                  | 0.000013 |
| Waiting for query cache lock   | 0.000002 |
| freeing items                  | 0.000002 |
| storing result in query cache  | 0.000003 |
| logging slow query             | 0.000002 |
| cleaning up                    | 0.000003 |
+--------------------------------+----------+

No puedo sacar demasiada información del perfil, pero menciona una tabla temporal, suficiente (para mí) para validar mi conclusión.