Не можете да създадете индекс за изглед:http:/ /dev.mysql.com/doc/refman/5.7/en/view-restrictions.html , така че трябва да се надявате, че индексът ще бъде използван. https://stackoverflow.com/a/7922711/3595565
Заобиколно решение
Има заобиколно решение, споменато в коментарите на друга част от документацията:https://dev.mysql.com/doc/refman/5.5/en/create-view.html В която създавате обикновена таблица и задавате своя специализиран индекс и зареждате данните от изгледа в таблицата.
LOCK TABLES materializedView WRITE;
TRUNCATE materializedView;
INSERT INTO materializedView SELECT * FROM regularView;
UNLOCK TABLES;
Защо вашата заявка не използва индексите?
Когато използвате UNION
в SELECT
mysql създава временна таблица за запазване на данните. По този начин, тъй като изгледът е „пряк път“ за вашата по-сложна заявка, при извикване на select той отново ще изпълни обединението, ще използва временна таблица... използвайте алгоритъма за изкушение, за да обработите данните.
Проверка на ръководството отново:http://dev.mysql. com/doc/refman/5.7/en/view-restrictions.html
Заключение :UNION
във вашата заявка пречи на изгледа да използва индексите.
Източници
въпрос във форума на mysql за същия проблем отговор:
отчет за грешка "НЕ СЪЗДАВАЙТЕ ВРЕМЕННИ ТАБЛИЦИ ЗА UNION ALL"
Поправено в MySQL 5.7 http:/ /dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-3.html
Някои тестови данни за проверка на профайлъра
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;
Проверете профайлъра:
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 |
+--------------------------------+----------+
Не мога да извадя твърде много информация от профила, но споменава временна таблица, достатъчно (за мен), за да потвърдя заключението си.