Php 在一个API请求中包含多个连接的单个查询,还是在单独的API请求中包含一些连接的几个查询?

Php 在一个API请求中包含多个连接的单个查询,还是在单独的API请求中包含一些连接的几个查询?,php,mysql,performance,api,join,Php,Mysql,Performance,Api,Join,什么是最佳实践,什么提供了最佳性能 我目前有一个查询,其中包含许多左连接s,用于获取用户及其所有数据,如好友、好友请求等: SELECT `user`.`id` AS `user_id`, `user`.`name` AS `user_name`, `manager`.`id` AS `manager_id`, `competition`.`id` AS `manager_competition_id`, `competition`.`name` AS `

什么是最佳实践,什么提供了最佳性能

我目前有一个查询,其中包含许多
左连接
s,用于获取
用户
及其所有数据,如好友、好友请求等:

SELECT
    `user`.`id` AS `user_id`,
    `user`.`name` AS `user_name`,
    `manager`.`id` AS `manager_id`,
    `competition`.`id` AS `manager_competition_id`,
    `competition`.`name` AS `manager_competition_name`,
    `competition`.`week` AS `manager_competition_week`,
    `country`.`id` AS `manager_competition_country_id`,
    `country`.`name` AS `manager_competition_country_name`,
    `club_template`.`id` AS `manager_club_template_id`,
    `club_template`.`name` AS `manager_club_template_name`,
    `club`.`id` AS `manager_club_id`,
    `club`.`name` AS `manager_club_name`,
    `club`.`ready` AS `manager_club_ready`,
    `friend`.`friend_id` AS `friend_id`,
    `friend_user`.`name` AS `friend_name`
FROM
    `users` AS `user`
LEFT JOIN
    `managers` AS `manager`
ON
    `manager`.`user_id` = `user`.`id`
LEFT JOIN
    `competitions` AS `competition`
ON
    `competition`.`id` = `manager`.`competition_id`
LEFT JOIN
    `countries` AS `country`
ON
    `country`.`id` = `competition`.`country_id`
LEFT JOIN
    `club_templates` AS `club_template`
ON
    `club_template`.`id` = `manager`.`club_template_id`
LEFT JOIN
    `clubs` AS `club`
ON
    `club`.`id` = `manager`.`club_id`
LEFT JOIN
    `friends` AS `friend`
ON
    `friend`.`user_id` = `user`.`id`
LEFT JOIN
    `users` AS `friend_user`
ON
    `friend_user`.`id` = `friend`.`friend_id`
WHERE
    `user`.`id` = 1
正如你所看到的,这是一个非常大的问题。我的理由是,最好只有一个查询可以在一个API请求中完成,就像这样

/api/users/1
/api/users/1
/api/users/1/friends
/api/users/1/friend_requests
/api/users/1/managers
…而不是几个查询,每个查询都在各自的API请求中,如下所示

/api/users/1
/api/users/1
/api/users/1/friends
/api/users/1/friend_requests
/api/users/1/managers
但现在我担心的是,由于它已经成为一个如此庞大的查询,它实际上会对性能造成更大的伤害,而不是将其拆分为单独的API请求

什么能更好地扩展

更新

我已将查询更改为完整查询。这不是最终的查询;我计划添加更多连接(或不添加,取决于答案)


每个表在
id
上都有一个
主键。所有协会栏(
competition\u id
club\u id
,等等)都有一个常规的
索引。数据库引擎是InnoDB。

在这两个引擎中,我推荐后者:许多小生境查询。它使调用者能够灵活地收回他们想要的内容,并且不太可能默默地引入性能问题(例如,只有一个检索数据的选项,因此每个人都会使用它,不管他们实际感兴趣的数据子集有多小)

这就是说,它当然不能避免性能问题,它只是意味着调用方可能会通过发出如此多的API调用而更加意识到这些问题

不过,你可以同时提供这两种服务。从您的命名约定中明确指出,昂贵的版本会收回所有数据,并在用户可能需要打20-30个电话才能了解全部情况时使用

示例:

1-想象一下,必须获取完整的用户对象才能找到名称。真是浪费。如果在一个大循环中不经意地完成了,那么性能陷阱将随时发生。更喜欢只读回一个值的
getUserName(id)
方法

2-另一方面,如果您想在页面中显示用户的完整配置文件,那么完整的
getFullUserProfile(id)
是最有效的(1次调用而不是10-20次)

编辑——另一个有用的例子。预测寻找多个值的位置,例如,与其强制调用方运行
getUserName(id)
500次以获取特定条件下的所有名称(可能是所有管理员用户?),不如提供一个
List getAdminUserNames()
,它在一次调用中提供所有数据。

这个问题很酷

我认为您需要担心查询背后的域概念,并尽可能忠实于这些概念

因此,根据您的查询进行粗略猜测,您有处于不同完成状态的用户—这些用户已经创建了他们的个人资料,但尚未加入竞争;已加入竞争但尚未成立俱乐部等的用户。这反映了您的域模型。我希望您的API能够反映这一点——因此使用restful示例:

/api/users/profile
/api/users/signedUpUsers/
/api/users/usersWithClubs/
第一次调用(/api/users/profile)允许您返回用户配置文件,但除了用户状态(可能还有可以找到其他附加数据的URL)之外,没有任何外部连接详细信息


坚持领域方法,并将性能测试构建到您的开发生命周期中;边走边优化,只有在证明有问题时才更改设计

如果您能够提供数据库结构和密钥以及完整的queryDone背后的一些信息,这将非常有用。如果你需要更多,请告诉我