sto cercando di interpretare il explain
di mysql in una query (scritto in due modi diversi), questo è il tavolo:Capire spiegare in una query mysql
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
Questo è il primo tipo di query:
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 ;
e questo è il secondo:
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 ;
le due query si chiedono la stessa cosa, l'unica la differenza è l'ordine di ref_table
(driving_table), nel primo caso è text_mess
, nel secondo caso è una query secondaria. primo risultato:
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
secondo risultato:
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
Come si può vedere la differenza è nell'ordine delle prime due linee, la mia domanda, in particolare, si trova al secondo (la query più veloce) la seconda riga dovrebbe essere la tabella interna, ma in tal caso, perché la colonna ref mi dice: max.dmess
, che dovrebbe essere la colonna della tabella di riferimento (sottoquery).
L'ultima riga si riferisce a come viene costruito il primo? Alla fine, pensi che ci sia una query più efficiente?
Su 'INNER JOIN's si consiglia di mettere la tabella con meno righe a sinistra (vale a dire la prima tabella). Il pianificatore di query MySQL è in grado di scambiare le tabelle per te se inserisci prima la tabella più grande (produce lo stesso risultato su 'EXPLAIN', indipendentemente dalla tabella che hai inserito per primo). In questo caso non può eseguire questa magia perché nelle tue query una delle tabelle 'JOIN'ed non è una tabella ma una sottoquery e questo impedisce di sapere quale tabella è più piccola. – axiac
La mia domanda è stata il risultato di spiegare: in particolare le righe con id 1, ed è la seguente: è giusto interpretare la prima riga del risultato di spiegare come "elaborazione" della tabella a sinistra del join e la seconda riga come "elaborazione" della tabella che si trova a destra del join, infine l'ultima riga è "elaborazione" della tabella. e interpretare giustamente (nella seconda query spiegare) il parametro max.dmess della colonna ref della seconda riga, come colonna da cui ogni riga viene confrontata con le righe della tabella text_mess (trovata tramite chiave: PRIMARY) –
emacos
Per prestazioni migliori , crea l'indice 'roger asc, sender asc, recipient asc, datamess desc' (o tutto desc). – Toni