让我们从昨天起采用一个简单的FQL
查询来获取用户朋友分享的所有链接,例如:
SELECT link_id, title, url, owner, created_time
FROM link
WHERE
created_time > strtotime('yesterday') AND
owner IN (
SELECT uid2 FROM friend WHERE uid1 = me()
)
LIMIT 100
如果用户有50个朋友,这将完美执行。但如果用户有数百个朋友,Facebook往往会返回错误。
选项:
如何正确查询Facebook以确保成功?
备注:
与超时相关的常见错误:
1
Fatal error: Uncaught Exception: 1: An unknown error occurred thrown in /..../facebook/php-sdk/src/base_facebook.php on line 708
第708行是一个异常错误:
// results are returned, errors are thrown
if (is_array($result) && isset($result['error_code'])) {
throw new FacebookApiException($result);
}
2
Fatal error: Uncaught CurlException: 52: SSL read: error:00000000:lib(0):func(0):reason(0), errno 104 thrown in /..../facebook/php-sdk/src/base_facebook.php on line 814
答案 0 :(得分:2)
你应该像你说的那样循环使用限制/偏移,或者像puffpio建议的那样预先缓存朋友列表。
你说它仍然无法可靠地工作 - 这是因为有些用户可能有很多很多链接,而其他用户可能没那么多。另请注意,您可能正在为某些用户检索未缓存的数据。我建议在循环中对失败的查询进行单次重试 - 通常情况下,第一个将超时,第二个将由于新缓存的数据而成功。
最后,对于子孙后代,我正在开展一项优化链接表的任务,以便在按时间过滤时更好地提高效率。
答案 1 :(得分:1)
某些数据库引擎不能很好地优化IN
关键字,或根本不优化。他们可能正在为查询的每个结果行执行in子句。你可以加入链接和朋友表而不是使用带子查询的IN吗?
您可能会发现this article很有趣。 (讨论MySQL上的IN子句性能问题,Facebook在后端运行MySQL。)
答案 2 :(得分:1)
最好缓存用户的朋友,偶尔刷新一下。 换句话说,运行此查询
SELECT uid2
FROM friend
WHERE uid1 = me()
缓存用户列表并运行
SELECT link_id, title, url, owner, created_time
FROM link
WHERE
created_time > strtotime('yesterday') AND
owner IN (/*your user list here*/)
LIMIT 100
这样您就不会一直运行内部查询。实际上,用户的朋友列表没有高流失率,因此您无需像获取共享链接那样频繁地更新它。
此外,以这种方式构建它将允许您将第二个查询分解为具有不同“所有者”集的多个查询,然后使用fql.multiquery
同时获取它们