Если типов доступа не много (скажем, 3: всем, друзьям, владельцу), то можно хранить три списка. Если много, то можно кешировать записи с запасом, скажем 100 (записи о фотках очень мало будут весить) и на стороне скрипта (пхп, питон, что там у Вас) решать, какие показывать, а какие нет для конкретного пользователя.
Если более кратко, то БД масштабируется несколько сложнее, чем web-сервера, поэтому иногда намного выгоднее закэшировать довольно большие куски данных, а потом обрабатывать их уже скриптом, чем каждый раз дергать БД.
Думаю, стоит отметить такой момент: допустим, один из серверов с memcached «вылетел» только на время. Например, неполадки в сети или кончились коннекции. Клиент сохранит ключ на один из других серверов. А при следующем обращении старый сервер снова станет доступным и возмётся старое значение (если между выборками были изменения). Так что лучше не позволять клиенту использовать другие сервера при отказе одного.
Еще @ ни в коем случае нельзя использовать в циклах, так как работает она так: выставляется error_reporting в 0, вызывается Ваша ф-ция, выставляется error_reporting в старое значение. Так что если цикл длинный, то @ может существенно повлиять на скорость его прохождения.
Извиняюсь, говорил об ActiveRecord в Rails.
По поводу не делать одинаковых запросов - Вы про кэш? Если да, то выше Вы же сами написали отличный комментарий по этому поводу. Здесь больше всего подойдёт пункт 1 из него.
Если речь о чем-то другом (к сожалению на UoW гугл выдаёт University of Wollongong и ничего по теме), то извиняйте.
1. Это понятно. Я бы удивился, если бы он решал это только по паре параметров.
2. Чаще всего, но не всегда
3. если "сегодня один индекс оптимальный, через месяц другой", то я воспользуюсь "сегодня" explain, посмотрю, и если mysql не использует мой индекс и при использовании force index запрос работает быстрее, то оставлю запрос с force index. "через месяц" при изменении структуры таблицы я снова проделаю туже процедуру.
Да, MySQL к сожалению часто не правильно выбирает нужный индекс, Postres в этом плане получше.
ПС. Если Вы все ещё в поисках решения, то воспользуйтесь FORCE INDEX:)
Я работал с ActiveRecord.
Допустим я указываю, как Вы говорите "что мне нужно", а какие есть варианты у ORM, "как" мне это дать? Как он может оптимизировать этот момент?
В том примере (по ссылке в посте) сравнивалось использование varchar( например, 'html', 'plaintext'), enum('html', 'plaintext') и INT, где инт - идентификатор в таблице, где лежат 'html' и 'plaintext'. Первые два случая оказались равны по скорости (примерно), а второй медленнее из-за того, что приходилось делать join. Так что в контексте данного примера - все верно.
С другой стороны, если ситуация позволяет, то лучше действительно использовать int, так как это уменьшает размер таблицы, индекса (если он используется), соответственно повышается скорость. Только в этом случае придётся помнить, что 1, например, - это html, а 2 - это plaintext. И именно это "хардкодить", что не очень правильно, так как люди, читающие Ваш код, ничего не поймут.
Я лично использую INT, но все подробно документирую:)
Во-первых, этот кэш нужен только тогда, когда Вы получили некоторые данные, а потом забыли о том, что они у Вас уже есть и пытаетесь получить второй раз. Во-вторых, этот кэш действителен только на время выполнения текущего процесса и если Вам нужно где-то что-то сохранить, то для этого выгоднее использовать что-то вроде memcached, но это уже совсем другая история.
с INSERT IGNORE и ON DUPLICATE KEY UPDATE был не удачный пример. То, что Вы напишете с помощью ORM и то, что напишете сами, будет одним и тем же, только на разных языках. Я своим комментарием хотел сказать лишь то, что использование ORM не прибавит никакой оптимальности Вашим запросам. ORM не сможет создать нужные индексы или выбрать правильный для использования, а если и преобразует "*" во все поля из таблицы, то перед этим выполнит "desc tablename".
здесь речь идёт об оптимизации работы с MySQL, а ORM годится для составления только простых запросов типа select * from ... (максимум, JOIN сделать) и никакой оптимизации таким способом Вы не добьётесь. Вы где-нибудь видели ORM, который использует INSERT IGNORE или ON DUPLICATE KEY UPDATE?
при работе с большими объёмами данных, Limit спасает только частично. Если Вы укажите limit 10000, 20, то mysql будет бежать с самого начала таблицы, пока не насчитает 10000, и только тогда считает 20 записей. В простейшем случае этого можно избежать, запомнив, какой id мы выводили последним, и в условие добавить id>последний_ид limit 20. Если требуется сортировка по другим полям, то нужно создать "правильный" индекс по этим полям и в условиях явно указать, что больше чего, что меньше чего. Правда этим способом будет сложнее вывести "пагинатор" "1 2 3 4 5" и тд. Но учитывая то, что пользователи редко ходят дальше нескольких страниц, то вполне будет достаточно "следующая последняя".
я использовал http://wiki.rubyonrails.org/rails/pages/Tutorial и http://wiki.rubyonrails.org/rails/pages/Howtos. Сейчас в основном использую последнюю и http://rails.rubyonrails.com/
Да, поскаль... сам с него начинал:) Но, если честно, он мне не много дал. Всё равно, когда перешёл на си, уже кое-что с паскаля забылось, кое-что пришлось переучивать.
Если более кратко, то БД масштабируется несколько сложнее, чем web-сервера, поэтому иногда намного выгоднее закэшировать довольно большие куски данных, а потом обрабатывать их уже скриптом, чем каждый раз дергать БД.
С каких это пор лайти и энджиникс - акселераторы?
По поводу не делать одинаковых запросов - Вы про кэш? Если да, то выше Вы же сами написали отличный комментарий по этому поводу. Здесь больше всего подойдёт пункт 1 из него.
Если речь о чем-то другом (к сожалению на UoW гугл выдаёт University of Wollongong и ничего по теме), то извиняйте.
2. Чаще всего, но не всегда
3. если "сегодня один индекс оптимальный, через месяц другой", то я воспользуюсь "сегодня" explain, посмотрю, и если mysql не использует мой индекс и при использовании force index запрос работает быстрее, то оставлю запрос с force index. "через месяц" при изменении структуры таблицы я снова проделаю туже процедуру.
ПС. Если Вы все ещё в поисках решения, то воспользуйтесь FORCE INDEX:)
Допустим я указываю, как Вы говорите "что мне нужно", а какие есть варианты у ORM, "как" мне это дать? Как он может оптимизировать этот момент?
С другой стороны, если ситуация позволяет, то лучше действительно использовать int, так как это уменьшает размер таблицы, индекса (если он используется), соответственно повышается скорость. Только в этом случае придётся помнить, что 1, например, - это html, а 2 - это plaintext. И именно это "хардкодить", что не очень правильно, так как люди, читающие Ваш код, ничего не поймут.
Я лично использую INT, но все подробно документирую:)