Php 为什么这种连接效率低下?
我试图同时从多个表中获取数据。在我的旧系统中,我会进行查询,获取所需的数据,然后将其用于下一个查询。我希望避免进行多个查询,因此我将它们与联接结合起来:Php 为什么这种连接效率低下?,php,mysql,optimization,join,Php,Mysql,Optimization,Join,我试图同时从多个表中获取数据。在我的旧系统中,我会进行查询,获取所需的数据,然后将其用于下一个查询。我希望避免进行多个查询,因此我将它们与联接结合起来: SELECT `to`.`id` , `to`.`group`, `to`.`email`, `pTo`.`min_offer`, COUNT(`offerRes`.`id`), `settingsRes`.`email` FROM `members` AS `to`
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)从profiles表、offers表和user settings表中获取结果。这些表都有一个主id,所有内容都映射到该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
当MySQL可以做一个简单的查找,因为我的查询是基于主键id的,为什么MySQL要遍历profile字段中的所有45行
因为您要连接到子查询的结果,子查询将包括表中的每条记录:
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
非内部联接越多,查询的效率就越低。据我所知,使用内部联接,如果这些子查询中的任何一个子查询不返回任何行,则整个查询将返回NULL。这是不可取的。我仍然不明白,当它在idCol=someOtherIdCol上进行左连接时,为什么必须搜索所有45条记录。ID是主键。它不必搜索45行,除非我读的是“解释错误”?左连接应该检查45行。表成员的所有行都将出现在结果中,您无法找到另一个表对应的行将具有nullfields@Ignacio-这种情况下的效率与联接类型无关,而是使用派生表,可直接访问该表!你是说只执行多个查询更快?SE:ECT
f1
,f2
来自memnbers
其中id
=?限制1。。。从profile
中选择f1
,其中id
=?限制1。至少这将利用主键并进行快速查找。为了代码美观和效率(mysql调用越少=我认为越好),任何将它们结合起来的方法都是完美的。效率很高,运行正常。我不知道如何使用JOIN。我假设您需要指定在联合查询中需要哪些字段,以便以后可以“访问”这些变量(即,现在我可以在另一个查询中使用pTo
.min\u offer)。现在我知道你可以这样做了,为什么会有人像我以前那样使用子查询呢?这将大量查询合并为1,并且仍然保持效率。
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