Mysql
 sql >> база данни >  >> RDS >> Mysql

Индексът на Mysql в изглед не работи

Не можете да създадете индекс за изглед: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 |
+--------------------------------+----------+

Не мога да извадя твърде много информация от профила, но споменава временна таблица, достатъчно (за мен), за да потвърдя заключението си.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL:Защо 5-ти идентификатор в клаузата IN драстично променя плана на заявката?

  2. Как да съкратите таблицата в MySQL

  3. Функция за извикване на MySqlCommand

  4. Изберете оператор вътре в цикъл в Mysql Съхранена процедура

  5. Създайте MySQL функция в Laravel 5.5