Как я могу оптимизировать свой FQL, чтобы избежать тайм-аутов Facebook? - PullRequest
8 голосов
/ 30 августа 2011

Давайте возьмем простой запрос 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 - Конечно, это сработает, но каждый раз будет показывать одних и тех же друзей.Если вам не нужен канал только для Ivy League , это не очень полезно.
  2. Пакетные запросы - создание пакета запросов с использованием смещений и ограничение каждого из них до50. К сожалению, здесь тоже нет никаких улучшений.
  3. Loop It - Пока это лучшее, что я нашел.Перебирайте те же запросы, которые вы создали для пакетного запроса, но делайте это по одному с несколькими вызовами api fql запроса.Но даже это хит и мисс.

Как правильно запросить Facebook, чтобы обеспечить успешные результаты?

Примечания:

  • Я использую последнюю версию Facebook php sdk, 3.1.1
  • Я также пытался расширить параметры по умолчанию для тайм-аутов curl в base_facebook.php

CommonОшибки, связанные с Таймаутом:

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 ]

2 голосов
/ 31 августа 2011

Вы должны циклически использовать лимит / смещение, как вы сказали, или кешировать список друзей сразу, как предложил puffpio.

Вы сказали, что он все еще не работал надежно - это потому, что у некоторых пользователей может быть много-много ссылок, а у других не так много. Обратите внимание, что вы можете получать некэшированные данные для некоторых пользователей. Я бы порекомендовал сделать одну повторную попытку в цикле для неудачных запросов - часто случается так, что для первого из них истекает время ожидания, а для второго - из-за новых кэшированных данных.

Наконец, для потомков я открываю задачу по оптимизации таблицы ссылок, чтобы повысить эффективность работы, когда она фильтруется по времени.

1 голос
/ 31 августа 2011

Было бы лучше кэшировать друзей пользователя и обновлять его только изредка.Другими словами, выполните этот запрос

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, чтобы получить их все одновременно

1 голос
/ 30 августа 2011

Некоторые движки БД плохо или вообще не оптимизируют ключевое слово IN. Они могут выполнять предложение in для каждой результирующей строки вашего запроса. Можно ли объединить таблицы ссылок и друзей вместо использования IN с подзапросом?

Вы можете найти эту статью интересной. (Обсуждаются проблемы с производительностью предложения IN на MySQL, а Facebook запускает MySQL на стороне сервера.)

...