我的问题会很长,所以我尽量简短。我正在尝试优化MySQL中的查询,我写了两个版本。这两个返回完全相同的结果(如行数和列数和内容)。但是这两者的执行时间差别很大。奇怪的是,当我打印他们的explain
它们看起来几乎相同时,人们甚至会说较慢的一个应该更高性能!他们在这里:
平均执行时间: 0.0846秒
SQL:
SELECT SQL_CALC_FOUND_ROWS SQL_NO_CACHE
a.account_id
, MAX(mc_cp.phone_number) AS phone_number
FROM account a
INNER JOIN entity_revision er ON (a.entity_id = er.entity_id AND a.account_id = er.revision_id)
LEFT JOIN contact mc ON (a.contact_entity_id = mc.entity_id)
LEFT JOIN entity_revision mc_er ON (mc.entity_id = mc_er.entity_id AND mc.contact_id = mc_er.revision_id AND mc_er.state = 0)
LEFT JOIN contact_phone mc_cp ON (mc.contact_id = mc_cp.contact_id)
LEFT JOIN contact_email mc_ce ON (mc.contact_id = mc_ce.contact_id)
LEFT JOIN contact_website mc_cw ON (mc.contact_id = mc_cw.contact_id)
LEFT JOIN contact_address mc_ca ON (mc.contact_id = mc_ca.contact_id)
WHERE
er.state = 0
AND
a.type IN (1)
AND
(
a.account_id IN
(
SELECT ac.account_id
FROM account_contact ac
INNER JOIN contact c ON (ac.contact_entity_id = c.entity_id)
INNER JOIN entity_revision er ON (c.entity_id = er.entity_id AND c.contact_id = er.revision_id)
LEFT JOIN contact_phone cp ON (c.contact_id = cp.contact_id)
LEFT JOIN contact_email ce ON (c.contact_id = ce.contact_id)
LEFT JOIN contact_website cw ON (c.contact_id = cw.contact_id)
WHERE er.state = 0
)
OR
a.contact_entity_id IN
(
SELECT c.entity_id
FROM contact c
INNER JOIN entity_revision er ON (c.entity_id = er.entity_id AND c.contact_id = er.revision_id)
LEFT JOIN contact_phone cp ON (c.contact_id = cp.contact_id)
LEFT JOIN contact_email ce ON (c.contact_id = ce.contact_id)
LEFT JOIN contact_website cw ON (c.contact_id = cw.contact_id)
WHERE er.state = 0
)
)
GROUP BY a.account_id
ORDER BY name ASC
LIMIT 0, 75
explain
输出:
+----+--------------------+-------+--------+----------------------------------------------------------------+-------------------+---------+-----------------------------------------------+------+----------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------------+-------+--------+----------------------------------------------------------------+-------------------+---------+-----------------------------------------------+------+----------+----------------------------------------------+
| 1 | PRIMARY | a | ref | PRIMARY,inxName,inx_entity_id,fk_account_contact1_idx,inx_type | inx_type | 1 | const | 1361 | 100.00 | Using where; Using temporary; Using filesort |
| 1 | PRIMARY | mc | ref | inx_entity_id | inx_entity_id | 4 | db.a.contact_entity_id | 1 | 100.00 | Using index |
| 1 | PRIMARY | er | eq_ref | PRIMARY | PRIMARY | 9 | db.a.entity_id,db.a.account_id,const | 1 | 100.00 | Using index |
| 1 | PRIMARY | mc_er | eq_ref | PRIMARY | PRIMARY | 9 | db.mc.entity_id,db.mc.contact_id,const | 1 | 100.00 | Using index |
| 1 | PRIMARY | mc_cp | ref | Relationship1_idx | Relationship1_idx | 4 | db.mc.contact_id | 1 | 100.00 | NULL |
| 1 | PRIMARY | mc_ce | ref | Relationship1_idx | Relationship1_idx | 4 | db.mc.contact_id | 1 | 100.00 | NULL |
| 1 | PRIMARY | mc_cw | ref | Relationship1_idx | Relationship1_idx | 4 | db.mc.contact_id | 1 | 100.00 | NULL |
| 1 | PRIMARY | mc_ca | ref | Relationship1_idx | Relationship1_idx | 4 | db.mc.contact_id | 1 | 100.00 | NULL |
| 3 | DEPENDENT SUBQUERY | c | ref | PRIMARY,inx_entity_id | inx_entity_id | 4 | func | 1 | 100.00 | Using index |
| 3 | DEPENDENT SUBQUERY | er | eq_ref | PRIMARY | PRIMARY | 9 | func,db.c.contact_id,const | 1 | 100.00 | Using where; Using index |
| 3 | DEPENDENT SUBQUERY | cp | ref | Relationship1_idx | Relationship1_idx | 4 | db.c.contact_id | 1 | 100.00 | Using index |
| 3 | DEPENDENT SUBQUERY | ce | ref | Relationship1_idx | Relationship1_idx | 4 | db.c.contact_id | 1 | 100.00 | Using index |
| 3 | DEPENDENT SUBQUERY | cw | ref | Relationship1_idx | Relationship1_idx | 4 | db.c.contact_id | 1 | 100.00 | Using index |
| 2 | DEPENDENT SUBQUERY | ac | ref | PRIMARY,fk_account_contact1,fk_account_contact_account1_idx | PRIMARY | 4 | func | 1 | 100.00 | Using index |
| 2 | DEPENDENT SUBQUERY | c | ref | PRIMARY,inx_entity_id | inx_entity_id | 4 | db.ac.contact_entity_id | 1 | 100.00 | Using index |
| 2 | DEPENDENT SUBQUERY | er | eq_ref | PRIMARY | PRIMARY | 9 | db.ac.contact_entity_id,db.c.contact_id,const | 1 | 100.00 | Using index |
| 2 | DEPENDENT SUBQUERY | cp | ref | Relationship1_idx | Relationship1_idx | 4 | db.c.contact_id | 1 | 100.00 | Using index |
| 2 | DEPENDENT SUBQUERY | ce | ref | Relationship1_idx | Relationship1_idx | 4 | db.c.contact_id | 1 | 100.00 | Using index |
| 2 | DEPENDENT SUBQUERY | cw | ref | Relationship1_idx | Relationship1_idx | 4 | db.c.contact_id | 1 | 100.00 | Using index |
+----+--------------------+-------+--------+----------------------------------------------------------------+-------------------+---------+-----------------------------------------------+------+----------+----------------------------------------------+
19 rows in set, 1 warning (0.00 sec)
平均执行时间: 0.32078秒
SQL:
SELECT SQL_CALC_FOUND_ROWS SQL_NO_CACHE
a.account_id
, MAX(IF(mc_cp.phone_number) AS phone_number
FROM account a
INNER JOIN entity_revision er ON (a.entity_id = er.entity_id AND a.account_id = er.revision_id)
LEFT JOIN contact mc ON (a.contact_entity_id = mc.entity_id)
LEFT JOIN entity_revision mc_er ON (mc.entity_id = mc_er.entity_id AND mc.contact_id = mc_er.revision_id AND mc_er.state = 0)
LEFT JOIN contact_phone mc_cp ON (mc.contact_id = mc_cp.contact_id)
LEFT JOIN contact_email mc_ce ON (mc.contact_id = mc_ce.contact_id)
LEFT JOIN contact_website mc_cw ON (mc.contact_id = mc_cw.contact_id)
LEFT JOIN contact_address mc_ca ON (mc.contact_id = mc_ca.contact_id)
LEFT JOIN contact smc ON (a.contact_entity_id = smc.entity_id)
LEFT JOIN entity_revision smc_er ON (smc.entity_id = smc_er.entity_id AND smc.contact_id = smc_er.revision_id AND smc_er.state = 0)
LEFT JOIN contact_phone smc_cp ON (smc.contact_id = smc_cp.contact_id)
LEFT JOIN contact_email smc_ce ON (smc.contact_id = smc_ce.contact_id)
LEFT JOIN contact_website smc_cw ON (smc.contact_id = smc_cw.contact_id)
LEFT JOIN contact_address smc_ca ON (smc.contact_id = smc_ca.contact_id)
LEFT JOIN account_contact sac ON (a.account_id = sac.account_id)
LEFT JOIN contact sc ON (sac.contact_entity_id = sc.entity_id)
LEFT JOIN entity_revision ser ON (sc.entity_id = ser.entity_id AND sc.contact_id = ser.revision_id AND ser.state = 0)
LEFT JOIN contact_phone scp ON (sc.contact_id = scp.contact_id)
LEFT JOIN contact_email sce ON (sc.contact_id = sce.contact_id)
LEFT JOIN contact_website scw ON (sc.contact_id = scw.contact_id)
WHERE
er.state = 0
AND
a.type IN (1)
GROUP BY a.account_id
ORDER BY name ASC
LIMIT 0, 75
explain
输出:
+----+-------------+--------+--------+----------------------------------------------------------------+-------------------+---------+------------------------------------------+------+----------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+--------+----------------------------------------------------------------+-------------------+---------+------------------------------------------+------+----------+----------------------------------------------+
| 1 | SIMPLE | a | ref | PRIMARY,inxName,inx_entity_id,fk_account_contact1_idx,inx_type | inx_type | 1 | const | 1361 | 100.00 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | mc | ref | inx_entity_id | inx_entity_id | 4 | db.a.contact_entity_id | 1 | 100.00 | Using index |
| 1 | SIMPLE | er | eq_ref | PRIMARY | PRIMARY | 9 | db.a.entity_id,db.a.account_id,const | 1 | 100.00 | Using index |
| 1 | SIMPLE | mc_er | eq_ref | PRIMARY | PRIMARY | 9 | db.mc.entity_id,db.mc.contact_id,const | 1 | 100.00 | Using index |
| 1 | SIMPLE | mc_cp | ref | Relationship1_idx | Relationship1_idx | 4 | db.mc.contact_id | 1 | 100.00 | NULL |
| 1 | SIMPLE | mc_ce | ref | Relationship1_idx | Relationship1_idx | 4 | db.mc.contact_id | 1 | 100.00 | NULL |
| 1 | SIMPLE | mc_cw | ref | Relationship1_idx | Relationship1_idx | 4 | db.mc.contact_id | 1 | 100.00 | NULL |
| 1 | SIMPLE | mc_ca | ref | Relationship1_idx | Relationship1_idx | 4 | db.mc.contact_id | 1 | 100.00 | NULL |
| 1 | SIMPLE | smc | ref | inx_entity_id | inx_entity_id | 4 | db.a.contact_entity_id | 1 | 100.00 | Using index |
| 1 | SIMPLE | smc_er | eq_ref | PRIMARY | PRIMARY | 9 | db.smc.entity_id,db.smc.contact_id,const | 1 | 100.00 | Using index |
| 1 | SIMPLE | smc_cp | ref | Relationship1_idx | Relationship1_idx | 4 | db.smc.contact_id | 1 | 100.00 | Using index |
| 1 | SIMPLE | smc_ce | ref | Relationship1_idx | Relationship1_idx | 4 | db.smc.contact_id | 1 | 100.00 | Using index |
| 1 | SIMPLE | smc_cw | ref | Relationship1_idx | Relationship1_idx | 4 | db.smc.contact_id | 1 | 100.00 | Using index |
| 1 | SIMPLE | smc_ca | ref | Relationship1_idx | Relationship1_idx | 4 | db.smc.contact_id | 1 | 100.00 | Using index |
| 1 | SIMPLE | sac | ref | PRIMARY,fk_account_contact_account1_idx | PRIMARY | 4 | db.a.account_id | 1 | 100.00 | Using index |
| 1 | SIMPLE | sc | ref | inx_entity_id | inx_entity_id | 4 | db.sac.contact_entity_id | 1 | 100.00 | Using index |
| 1 | SIMPLE | ser | eq_ref | PRIMARY | PRIMARY | 9 | db.sc.entity_id,db.sc.contact_id,const | 1 | 100.00 | Using index |
| 1 | SIMPLE | scp | ref | Relationship1_idx | Relationship1_idx | 4 | db.sc.contact_id | 1 | 100.00 | Using index |
| 1 | SIMPLE | sce | ref | Relationship1_idx | Relationship1_idx | 4 | db.sc.contact_id | 1 | 100.00 | Using index |
| 1 | SIMPLE | scw | ref | Relationship1_idx | Relationship1_idx | 4 | db.sc.contact_id | 1 | 100.00 | Using index |
+----+-------------+--------+--------+----------------------------------------------------------------+-------------------+---------+------------------------------------------+------+----------+----------------------------------------------+
20 rows in set, 1 warning (0.00 sec)
这不奇怪吗?我错过了什么吗?