2015-06-04 4 views
7

Ich versuche, die explain von MySQL in einer Abfrage (geschrieben auf zwei verschiedene Arten) zu interpretieren, ist dies die Tabelle:Verstehen ERKLäRT in einer MySQL-Abfrage

create table text_mess(
    datamess timestamp(3) DEFAULT 0, 
    sender bigint , 
    recipient bigint , 
    roger boolean, 
    msg char(255), 
    foreign key(recipient) 
      references users (tel) 
         on delete cascade 
         on update cascade, 
primary key(datamess,sender) 
) 
engine = InnoDB 

Dies ist die erste Art der Abfrage:

EXPLAIN 
    select /*!STRAIGHT_JOIN*/datamess, sender,recipient,roger,msg 
    from text_mess join (select max(datamess)as dmess 
        from text_mess 
        where roger = true 
        group by sender,recipient) as max 
        on text_mess.datamess=max.dmess ; 

und das ist die zweite:

EXPLAIN 
    select /*!STRAIGHT_JOIN*/datamess, sender,recipient,roger,msg 
    from (select max(datamess)as dmess 
        from text_mess 
        where roger = true 
        group by sender,recipient) as max 
     join 
    text_mess 
    on max.dmess = text_mess.datamess ; 

die beiden Abfragen werden die gleiche Sache zu fragen, die einzige Unterschied ist die Reihenfolge von ref_table (driving_table), im ersten Fall ist text_mess, im zweiten Fall ist eine Unterabfrage. erstes Ergebnis:

id select_type  table  type possible_keys key  key_len  ref       rows  Extra 
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
    1 PRIMARY  text_mess  ALL  PRIMARY   null  null null       294225  null 
    1 PRIMARY  derived2  ref  auto_key0  auto_key0 7  inextremis.text_mess.datamess 10   Using index 
    2 DERIVED  text_mess  ALL  recipient  null  null null       294225  Using where; Using temporary; Using filesort 

zweites Ergebnis:

id select_type  table  type possible_keys key   key_len ref  rows Extra 
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 
    1 PRIMARY  <derived2>  ALL  null   null   null  null  294225 Using where 
    1 PRIMARY  text_mess  ref  PRIMARY   PRIMARY   6  max.dmess 1 null 
    2 DERIVED  text_mess  ALL  recipient  null   null  null  294225 Using where; Using temporary; Using filesort 

Wie Sie der Unterschied in der Reihenfolge der ersten beiden Zeilen sehen können, meine Frage ist vor allem auf dem zweiten (die schnellere Abfrage) die zweite Zeile sollte die innere Tabelle sein, aber wenn ja, warum die Spalte ref sagt mir: max.dmess, das sollte die Spalte der Ref-Tabelle (Unterabfrage) sein.

Wird die letzte Zeile darauf bezogen, wie die erste erstellt wird? Am Ende denken Sie, es gibt eine effizientere Abfrage?

+0

Bei 'INNER JOIN's wird empfohlen, die Tabelle mit weniger Reihen auf der linken Seite zu platzieren (d. H. Die erste Tabelle). Der MySQL-Abfrageplaner ist in der Lage, die Tabellen für Sie zu tauschen, wenn Sie die größte Tabelle zuerst setzen (es erzeugt das gleiche Ergebnis auf "EXPLAIN", egal, welche Tabelle Sie zuerst gesetzt haben). In diesem Fall kann es diese Magie nicht ausführen, da eine Ihrer 'JOIN'ed-Tabellen keine Abfrage, sondern eine Unterabfrage ist, die nicht wissen kann, welche Tabelle kleiner ist. – axiac

+0

Meine Frage war das Ergebnis von EXPLAIN: insbesondere die Zeilen mit ID 1, und ist wie folgt: ist es richtig, die erste Zeile des Ergebnisses von EXPLAIN als die "Verarbeitung" der Tabelle auf der linken Seite zu interpretieren Beitreten und die zweite Zeile als "Verarbeitung" der Tabelle, die rechts von der Join ist, schließlich ist die letzte Zeile "Verarbeitung" der Tabelle . und richtig interpretieren (in der zweiten Abfrage zu erklären) die Spalte max.dmess der ref in der zweiten Zeile, als die Spalte, aus der jede Zeile mit den Zeilen der Tabelle text_mess (gefunden über Schlüssel: PRIMARY) – emacos

+0

für eine bessere Leistung verglichen wird , Erstelle Index 'roger asc, Absender asc, Empfänger asc, datamess desc' (oder alle desc). – Toni

Antwort

0

Ich denke, die Antwort ist die Tabelle Scan vs Primärschlüssel. Wenn Sie sehen, von der ersten Abfrage, wird MySQL keine Tasten verwenden, aber bereit, jede Zeile aus der Tabelle „text_mess“:

id select_type  table  type possible_keys key  key_len  ref       rows  Extra 
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

    1 PRIMARY  text_mess  ALL  PRIMARY   null  null null       294225  null 

Aber Sie verwenden eine „ON“ Erklärung über den „Derived2“ Tisch und MySQL Erstellen Sie einen Autoschlüssel:

id select_type  table  type possible_keys key  key_len  ref       rows  Extra 
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
    1 PRIMARY  derived2  ref  auto_key0  auto_key0 7  inextremis.text_mess.datamess 10   Using index 

Dieser Schlüssel ist nicht vorhanden, also sollte MySQL es erstellen.

Wenn Sie Ihr zweites Beispiel nehmen, ist nun mal die vollständige Tabellen-Scan auf der „Derived2“ Tisch und Ihr Primärschlüssel aus der „text_mess“ ist im Einsatz:

id select_type  table  type possible_keys key   key_len ref  rows Extra 
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 
    1 PRIMARY  <derived2>  ALL  null   null   null  null  294225 Using where 
    1 PRIMARY  text_mess  ref  PRIMARY   PRIMARY   6  max.dmess 1 null 

Die Antwort ist, dass auf einem solchen Eine Situation, in der sich MySQL zum Erstellen und Verwenden eines Index entschieden hat, aber im Allgemeinen wird ein vollständiger Tabellenscan durchgeführt, der einfach schneller ist.

Stellen Sie sich vor, dass der Schlüssel auto_key0 die einzige Spalte aus dieser Unterabfrage wieder enthält. Dieser zusätzliche Prozess ist nicht notwendig. Deshalb ist Ihre zweite Abfrage schneller.