I am trying to interpret the explain
of mysql in a query(written in two different ways),this is the table:
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
This is the first type of 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 ;
and this is the second:
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 ;
the two queries are asking the same thing, the only difference is the order of ref_table
(driving_table), in the first case is text_mess
, in the second case is a sub query.
first result:
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
second result:
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
As you can see the difference is in the order of the first two lines, my question in particular is on the second (the faster query)
the second line should be the inner-table, but if so, why the column ref tells me: max.dmess
, that should be the column of the ref-table (sub-query).
Is the last row referred on how the first is built? In the end, you think there is a more efficient query?
INNER JOIN
s it's recommended to put the table with less rows on the left (i.e. the first table). The MySQL query planner is able to swap the tables for you if you put the biggest table first (it produces the same result onEXPLAIN
, no matter what table you put first). In this case it cannot perform this magic because on your queries one of theJOIN
ed table is not a table but a subquery and this prevents it to know which table is smaller. – Flubroger asc, sender asc, recipient asc, datamess desc
(or all desc). – Streptokinase