2011-08-30 111 views
8

讓我們來簡單FQL查詢來獲取昨天以來通過用戶的朋友共享,例如所有鏈接:如何優化我的FQL以避免Facebook超時?

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. Loop It - 到目前爲止,這是我找到的最好的。循環執行爲批量查詢構建的相同查詢,但每次使用多個api fql查詢調用執行一個查詢。但即使這是打擊和錯過。

如何正確查詢Facebook以確保成功結果?

注:

  • 我使用的是最新的Facebook SDK PHP 3.1.1
  • 我也試過在base_facebook.php延長卷曲超時默認選項

與超時相關的常見錯誤:

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 

回答

2

您應該通過使用限制/等進行偏移環你說,或者像puffpio建議的那樣緩存朋友列表。

你說它仍然不能可靠地工作 - 這是因爲有些用戶可能有很多很多鏈接,而其他用戶可能沒有那麼多。另請注意,您可能正在爲某些用戶檢索未緩存的數據。我建議在循環中針對失敗的查詢進行一次重試 - 通常情況下,第一個將超時,第二個將由於新緩存的數據而成功。

最後,對於後代,我打開一個任務來優化鏈接表,以便在按時間過濾時更有效地提高效率。

+0

謝謝德魯。通過註釋base_facebook.php中的例外(708和814),我能夠移除錯誤。除了在過去一週內能夠通過500多個(洗牌)用戶的鏈接遍歷的方式外,還有一些例外。到目前爲止,它一直保持在500.我會看看是否可以找到另一個天花板時間。謝謝你的幫助。 – Ryan

+1

我只注意到created_time沒有編入索引。這可能解釋了超時問題。我也想過通過link_id進行排序,但事實證明link_id也不對應於created_time。似乎矯枉過正必須要求所有link_id纔能有效地拉動上週。但直到他們索引這一專欄,這是我們擁有的最好的。 – Ryan

1

一些數據庫引擎不優化IN關鍵字好,或根本。他們可能正在爲查詢的每一個結果行執行in子句。你可以加入鏈接和朋友表而不是在子查詢中使用IN嗎?

你可能會覺得this article有趣。 (在MySQL和Facebook上討論IN子句性能的問題在後端運行MySQL。)

+0

有趣。所有的FQL查詢只是索引列,所以我認爲這不是一個問題。我確實試圖在這裏列出一個內部爆發的ID列表。但我沒有看到任何改善。如果我切平面ID列表,我會得到與上面相同的結果。首先運行此查詢的唯一好處是,我可以對ID進行排序或洗牌,以避免較低的ID始終具有首選項。 – Ryan

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 

沒有運行內部查詢所有的時間這種方式。實際上,用戶的朋友列表的流失率並不高,因此您無需像獲取共享鏈接那樣頻繁更新它。

此外,架構這種方式可以讓你分手的第2個查詢與不同組的「所有者,然後多個查詢使用fql.multiquery讓他們都同時

+0

作爲fql.multiquery做它不會幫助,如果他內存不足或超時。 –

+0

即使它能工作,通常也會出現此錯誤:「由於資源限制,此API調用無法完成」。循環播放,大量用戶ID似乎是最一致的。 – Ryan