Odpowiedź na to pytanie zależy od tego, czy używasz mysql przed 5.7, czy 5.7 i później. Być może nieco zmienię twoje pytanie, ale mam nadzieję, że poniższe uchwyci to, czego szukasz.
Twój SELECT * FROM Table
skanuje tabelę za pomocą indeksu klastrowego (fizycznej kolejności). W przypadku braku klucza podstawowego, jednym z nich jest niejawnie
dostępne dla silnika. Nie ma klauzuli gdzie, jak mówisz. Nie podjęto próby filtrowania ani wyboru innego indeksu.
Wyjaśnij
dane wyjściowe (patrz również
) pokazuje w podsumowaniu 1 wiersz. To jest stosunkowo proste. Wyjaśnij dane wyjściowe i wydajność za pomocą tabeli pochodnej B
będzie się różnić w zależności od tego, czy korzystasz z wersji przed 5.7, czy 5.7 i później.
Dokument Tabele pochodne w MySQL 5.7 opisuje to dobrze dla wersji 5.6 i 5.7, gdzie ta ostatnia nie zapewni żadnej kary ze względu na zmianę danych wyjściowych zmaterializowanej tabeli pochodnej, która jest włączana do zapytania zewnętrznego. W poprzednich wersjach znaczne obciążenie było znoszone w przypadku tabel tymczasowych z danymi pochodnymi.
Bardzo łatwo jest przetestować spadek wydajności przed wersją 5.7. Wystarczy średniej wielkości tabela, aby zobaczyć zauważalny wpływ tabeli pochodnej pytania na wydajność. Poniższy przykład znajduje się na małym stoliku w wersji 5.6:
explain
select qm1.title
from questions_mysql qm1
join questions_mysql qm2
on qm2.qid<qm1.qid
where qm1.qid>3333 and qm1.status='O';
+----+-------------+-------+-------+-----------------+---------+---------+------+-------+------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+-----------------+---------+---------+------+-------+------------------------------------------------+
| 1 | SIMPLE | qm1 | range | PRIMARY,cactus1 | PRIMARY | 4 | NULL | 5441 | Using where |
| 1 | SIMPLE | qm2 | ALL | PRIMARY,cactus1 | NULL | NULL | NULL | 10882 | Range checked for each record (index map: 0x3) |
+----+-------------+-------+-------+-----------------+---------+---------+------+-------+------------------------------------------------+
explain
select b.title from
( select qid,title from questions_mysql where qid>3333 and status='O'
) b
join questions_mysql qm2
on qm2.qid<b.qid;
+----+-------------+-----------------+-------+-----------------+---------+---------+------+-------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------------+-------+-----------------+---------+---------+------+-------+----------------------------------------------------+
| 1 | PRIMARY | qm2 | index | PRIMARY,cactus1 | cactus1 | 10 | NULL | 10882 | Using index |
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 5441 | Using where; Using join buffer (Block Nested Loop) |
| 2 | DERIVED | questions_mysql | range | PRIMARY,cactus1 | PRIMARY | 4 | NULL | 5441 | Using where |
+----+-------------+-----------------+-------+-----------------+---------+---------+------+-------+----------------------------------------------------+
Zauważ, że zmieniłem pytanie, ale ilustruje ono wpływ, jaki mają tabele pochodne i ich brak użycia indeksu w optymalizatorze w wersjach wcześniejszych niż 5.7. Tabela pochodna korzysta z indeksów, gdy jest materializowana. Ale później jest to tabela tymczasowa i jest włączana do zewnętrznego zapytania bez użycia indeksu. Tak nie jest w wersji 5.7