如何优化我的FQL以避免Facebook超时?

时间:2011-08-30 19:20:11

标签: facebook facebook-fql

让我们从昨天起采用一个简单的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往往会返回错误。

选项:

  1. 将朋友选择查询限制为50 - 当然,这将有效,但每次都会显示相同的朋友。除非你想要一个常春藤联盟提要,否则这不是很有帮助。
  2. 批量查询 - 使用偏移量创建一批查询,并将每个查询限制为50.不幸的是,此处也没有任何改进。
  3. 循环 - 到目前为止,这是我发现的最好的。循环遍历为批处理查询构建的相同查询,但是使用多个api fql查询调用一次执行一个查询。但即便如此也是如此。
  4. 如何正确查询Facebook以确保成功?

    备注:

    • 我正在使用最新的Facebook php sdk,3.1.1
    • 我也试过在base_facebook.php中扩展curl超时的默认选项

    与超时相关的常见错误:

    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
    

3 个答案:

答案 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同时获取它们