sql >> Database >  >> RDS >> Mysql

Prestatiestraf voor geneste mysql-query's

Het antwoord op deze vraag hangt af van of u mysql vóór 5.7 of 5.7 en daarna gebruikt. Het kan zijn dat ik uw vraag enigszins aanpas, maar hopelijk geeft het volgende weer wat u zoekt.

Uw SELECT * FROM Table doet een tabelscan via de geclusterde index (de fysieke ordening). In het geval van geen primaire sleutel, is er een impliciet beschikbaar voor de motor. Er is geen waar-clausule zoals je zegt. Er wordt niet geprobeerd te filteren of een andere index te kiezen.

De Uitleggen uitvoer (zie ook ) toont 1 rij in zijn samenvatting. Het is relatief rechttoe rechtaan. De uitvoer en prestaties uitleggen met uw afgeleide tabel B zal verschillen afhankelijk van of u een versie vóór 5.7 of 5.7 en later gebruikt.

Het document Afgeleide tabellen in MySQL 5.7 beschrijft het goed voor versies 5.6 en 5.7, waar de laatste geen straf oplevert vanwege de wijziging in de gerealiseerde afgeleide tabeluitvoer die wordt opgenomen in de buitenste query. In eerdere versies was er een aanzienlijke overhead met tijdelijke tabellen met de afgeleide.

Het is vrij eenvoudig om de prestatiestraf vóór 5.7 te testen. Het enige dat nodig is, is een middelgrote tabel om de merkbare impact te zien die de afgeleide tabel van uw vraag heeft op de prestatie. Het volgende voorbeeld staat op een kleine tafel in versie 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                                        |
+----+-------------+-----------------+-------+-----------------+---------+---------+------+-------+----------------------------------------------------+

Let op, ik heb de vraag veranderd, maar het illustreert de impact die afgeleide tabellen en hun gebrek aan indexgebruik met de optimizer hebben in versies vóór 5.7. De afgeleide tabel profiteert van indexen terwijl deze wordt gerealiseerd. Maar daarna blijft het als een tijdelijke tabel overhead en wordt het zonder indexgebruik opgenomen in de buitenste query. Dit is niet het geval in versie 5.7




  1. MariaDB-waarschuwing:'[email protected]' heeft beide ... Het wachtwoord wordt genegeerd

  2. waarom kan ik deze tabel niet maken op Android SQLite?

  3. Vraag bijwerken met PDO en MySQL

  4. Oracle zweeft versus nummer