mysql 加入查询占用太多资源

mysql join query taking too many resources

我在 debian 上使用 python2.7 和 mysql5.5。

对于此查询 mysql 使用 100% cpu:

mysql> SHOW FULL PROCESSLIST;
+-----+------------------+-----------------+---------+---------+------+--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Id  | User             | Host            | db      | Command | Time | State        | Info                                                                                                                                                                                                          |
+-----+------------------+-----------------+---------+---------+------+--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 253 | whitewall        | localhost:39377 | mailing | Query   |    4 | Sending data | 
SELECT
    contacts.ID,
    contacts.RATING,
    mails.MANDRILL_ID
FROM contacts
    LEFT JOIN mails
        ON mails.CONTACT_ID = contacts.ID
HAVING mails.MANDRILL_ID = 'fea4b3b036b44655a7e24121ac359d0a' |

有什么可能出错的提示吗?

HAVING 更改为 WHERE

您的查询是根据此进程列表向您的客户端(您的 python 程序)传送结果集。这种状态下的查询很少见,除非结果集确实非常大。

您的查询,如所写,return将您 contacts table 中的每一行发送到您的 python 程序。如果您只想 return 与具有 MANDRILL_ID = 'fea4b3b036b44655a7e24121ac359d0a'mails 行相关的 contacts 行,请将您的 LEFT JOIN 更改为 JOIN

下面是编写查询的正确方法:

SELECT c.ID, c.RATING, c.MANDRILL_ID
FROM contacts c JOIN
     mails m
     ON m.CONTACT_ID = c.ID
WHERE m.MANDRILL_ID = 'fea4b3b036b44655a7e24121ac359d0a';

为了性能,您需要以下索引:mails(mandrill_id, contact_id)contacts(id)(您可能有后者)。

备注:

  • 无论如何 mails 上的条件都会将 left join 变成 join
  • having 子句实际上应该主要与 group by 一起使用。 MySQL 有扩展名,但您不需要它。使用 where.
  • 使用 having 可能会阻止优化器选择最佳优化路径。
  • Table 别名使查询更易于编写和阅读。