我想一次从多个表中获取数据。在我的旧系统中,我会进行查询,获取所需的数据,然后将其用于下一个查询。我想避免进行多次查询,所以我将它们与连接结合起来:
SELECT `to`.`id` , `to`.`group`, `to`.`email`, `pTo`.`min_offer`, COUNT(`offerRes`.`id`), `settingsRes`.`email`
FROM `members` AS `to`
LEFT JOIN (
SELECT `id` , `min_offer`
FROM `profile`
) pTo ON pTo.id = to.id
LEFT JOIN (
SELECT `id`, `from`,`to`
FROM `offers`
) offerRes ON offerRes.from = ? && offerRes.to = to.id
LEFT JOIN (
SELECT `id`, `email`
FROM `user_settings`
) settingsRes ON settingsRes.id = to.id
WHERE to.id = ? LIMIT 1
我使用传入的 ID (to.id) 从配置文件表、报价表和用户设置表中获取结果。这些表都有一个 PRIMARY id,所有内容都映射到该 primary id。我的 PHP 用户准备了语句,但是我替换了 ?在 PHPMyAdmin 中具有硬值。我的解释如下:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY to const PRIMARY PRIMARY 4 const 1
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 45
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 1
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 15
4 DERIVED user_settingsALL NULL NULL NULL NULL 15
3 DERIVED offers system NULL NULL NULL NULL 1
2 DERIVED profile ALL NULL NULL NULL NULL 45
当我的查询基于主键 id
时,为什么 MySQL 可以进行简单查找时却要遍历配置文件字段中的所有 45 行?有什么办法可以提高效率吗?我只需要一张包含以下内容的表格:
id (from members) - this is optional as this is what is obtained from the user and passed in to SELECT against
group (from members) - corresponding to the id that is passed in
email (from members) - corresponding to the id that is passed in
min_offer (from profile) - also corresponding to the id that is passed in
NUM_ROWS(from offers) - number of rows corresponding to the id taht is passed in and another number that is also passed in. The offers table has a PRIMARY id but it is a different ID than what is passed in.
email (from user_settings) - corresponding to the id that is passed in
最佳答案
Why is MySQL going through all 45 rows in the profile field when it can do a simple lookup as my query is based on the PRIMARY key id?
因为您要加入子查询的结果,其中将包括表中的每条记录:
LEFT JOIN (
SELECT `id` , `min_offer`
FROM `profile`
) pTo ON pTo.id = to.id
-- etc.
相反,直接加入表:
LEFT JOIN `profile` AS pTo ON pTo.id = to.id
LEFT JOIN `offers` AS offerRes ON offerRes.from = ? && offerRes.to = to.id
LEFT JOIN `user_settings` AS settingsRes ON settingsRes.id = to.id
关于php - 为什么这个 JOIN 效率低下?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9746860/