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 别名使查询更易于编写和阅读。
我在 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 别名使查询更易于编写和阅读。