Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Mysql index on view funktioniert nicht

Sie können keinen Index für eine Ansicht erstellen:http:/ /dev.mysql.com/doc/refman/5.7/en/view-restrictions.html , also müssen Sie hoffen, dass der Index verwendet wird. https://stackoverflow.com/a/7922711/3595565

Problemumgehung

In den Kommentaren eines anderen Teils der Dokumentation wird ein Workaround erwähnt:https://dev.mysql.com/doc/refman/5.5/en/create-view.html In dem Sie eine reguläre Tabelle erstellen und Ihren spezialisierten Index setzen und die Daten aus der Ansicht in die Tabelle laden.

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

Warum verwendet Ihre Abfrage die Indizes nicht?

Bei Verwendung von UNION in einem SELECT mysql erstellt eine temporäre Tabelle, um die Daten zu speichern. Da eine Ansicht also eine "Verknüpfung" für Ihre komplexere Abfrage ist, wird sie beim Aufrufen der Auswahl erneut die Vereinigung ausführen, eine temporäre Tabelle verwenden ... den versuchbaren Algorithmus verwenden, um die Daten zu verarbeiten.

Überprüfen Sie erneut das Handbuch:http://dev.mysql. com/doc/refman/5.7/en/view-restrictions.html

Fazit :Die UNION in Ihrer Abfrage hindert die Ansicht daran, die Indizes zu verwenden.

Quellen

Frage im MySQL-Forum zum selben Problem Antwort:

Fehlerbericht "KEINE TEMPORÄREN TABELLEN FÜR UNION ALL ERSTELLEN"

Behoben in MySQL 5.7 http:/ /dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-3.html

Einige Testdaten, um den Profiler zu überprüfen

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;

Prüfen Sie den Profiler:

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 |
+--------------------------------+----------+

Ich kann dem Profil nicht allzu viele Informationen entnehmen, aber es erwähnt eine temporäre Tabelle, genug (für mich), um meine Schlussfolgerung zu bestätigen.