Администратор
Кому интересно - формирование ленты происходит примерно так.
Идет обращение к базе - выбирается группа тех, кто есть в избранном у данного пользователя (с проверкой права на доступ к дневнику). Причем проверка шарашит по всей базе пользователей.
Затем у обнаруженных избранных выбираются записи, сделанные после даты Х. При этом проверяется еще и право доступа к кажой конкретной записи.
Наконец все это разбивается на страницы (учитывая выбранное число вывода для конкретного юзера).
В часы пик сервер, мягко скажем, не радуется.
Если у кого-то есть внятные мысли по поводу оптимизации запросов - будем рады выслушать.
Идет обращение к базе - выбирается группа тех, кто есть в избранном у данного пользователя (с проверкой права на доступ к дневнику). Причем проверка шарашит по всей базе пользователей.
Затем у обнаруженных избранных выбираются записи, сделанные после даты Х. При этом проверяется еще и право доступа к кажой конкретной записи.
Наконец все это разбивается на страницы (учитывая выбранное число вывода для конкретного юзера).
В часы пик сервер, мягко скажем, не радуется.
Если у кого-то есть внятные мысли по поводу оптимизации запросов - будем рады выслушать.
29.10.2005 в 13:10
Я помню не только СМ-4 и 1420, но и ЭВМ ЕС-1020, блин.
29.10.2005 в 13:12
ЕС не считается, там UNIX'а не было
29.10.2005 в 16:18
Не пора ли закрывать тему, а?
29.10.2005 в 16:46
зачем просить высказать мысли по оптимизации запросов, если никто не знает ни структуры базы данных, ни самих этих запросов?
29.10.2005 в 17:09
29.10.2005 в 17:34
29.10.2005 в 17:38
29.10.2005 в 17:51
29.10.2005 в 17:56
грамотно ее сделать и разгрузка будет неплохая, так как любой нормальный человек знает что такое rss и вовсю этим пользуется...
29.10.2005 в 18:29
Я достаточно долго занимался оптимизацией хранения информации, да и вопросами паралеллизации тоже занимался, потому я бы всё-таки сказал, что проблема не в поиске, а в забивании коннекшинов к SQL серверам данными. Фактически, после каждой выборки SQL сервер отдайт ВЕСЬ ответ клиенту коннекшина, и пока он не передал этот ответ, этот коннекшин так и висит в памяти и мешает подключится другим SQL клиентам. Простой и верный метод оптимизации этой херни - разделить индексы и тело постов. Например следующим способом: при написании поста (например коммента) в БД кидается некий UID этого текста, права на него, принадлежность к группам (оптималь это сделать не флагами, а разнести по разным колонкам, как булевские переменные), а сам текст скидывается, как файл в некую директорию, причём имя этого файла как раз этот UID из БД и есть. Применительно к дневникам для более быстрого поиска текстового фрагмента это может выглядеть, как /ID_участника/часовой_timestamp/UID_записи где часовой timestamp - это UNIX time по модулю 3600, например. Соответственно, синхронизировать текстовую часть базы данных становится невпример легче (наиболее верно её хранить прямо на отдающих web серверах - процессорах), включать её можно простым инклудом и SQL серваки не будут мучится, отдавая полные тексты. Такой подход гарантирует примерно 60-80% прирост производительности. А если добавить динамическую синхронизацию данных, то и все 120, ведь обращение к файловой системе заведомо быстрее, чем работа через сокеты. (Под динамической синхронизацией я имею ввиду схему, при которой тексты хранятся на отдельном, выделеном серваке и одновременно кэшируются на отдающих web серверах - если какого-то текста нет в кэше, то идет запрос на отдачу текста с выделеного сервака, после чего этот текст кэшируется на отдающем сервере и больше он между серверами не не пересылается. А система таймстампов позволяет в этом случае эффективно очищать роботом устарелый кэш.).
Есть и другой подход - тоже индексы разделяются с текстами, но тексты хранятся на специальном SQL сервере, который заточен только под отдачу данных. В этом случае индекс берётся из одного коннекшина, а данные отдаются с другого сервера. Структуировать БД при этом стоит примерно так же, как и в предидущем примере с файловой системой - с обязательным заведением timestamp - таблиц. Такой подход более масштабиремый на увеличение машин (легче синхронизировать тела постов), но и даёт меньший прирост производительности.
Последнее, про оптимизацию - при редактировании любого поста не нужно изменять сам пост, гораздо быстрее создать новую запись и объявить её актуальной (поставить булевский флаг, например), а уж потом время от времени собирать роботом неактуальные записи и удалять их.
29.10.2005 в 18:35
А так же попробуйте кэшировать новые записи в HEAP таблицах - при записи в таблицу она локируется (или тормозится) на некоторое время на чтение. Тобишь чем больше запросов на запись, тем больше будет тормозить чтение таблицы. Потому при большом вале запросов на запись стоит их отправлять в какую-нить промежуточную таблицу, заточенную только на приём новых сообщений, а потом уже валом брать оттуда весь дамп новых записей и пакетно их отправлять на store в основную БД (делать это омжно роботом с периодичностью, допустим, полсекунды).
29.10.2005 в 19:23
новый запрос просто ловит этот открытый коннекшн и пользует.
а так, я не думаю что дайрики пишут идиоты, чувак
29.10.2005 в 20:36
Вообще-то под коннекшином понимается не только открытый сокет до сервака, но и очередь запросов. Кстати, если бы там был только один открытый коннекшин - всё быстро бы очень нагнулось. Поскольку один коннекшин - это одна позиция в очереди и работать что-то может только если этот коннекшин является командным для запуска тучи хранимых процедур в новых нитках. А то пока по этому коннекшину сервак не отдаст ok report всё встаёт.
29.10.2005 в 22:04
а открывать новый connection или использовать старый - решит mySQL и php сами.
а так коннекшны вручную лучше не закрывать вручную. если не будут по ним работать - они автоматически закроются.
а если открывать каждым пользователем новый коннекшн - сервер быстро свалится к чертям.
29.10.2005 в 22:43
Мне интиресно, а с чего вы вдруг решили, что дневники на 100% написаны на PHP? Критические части запросто могут быть скомпилированы в отдельные модули - это раз, два - внутри PHP передать один конекшин из одной нитки (а каждая страница отрывается именно в своей нитке) в другую невозможно, поэтому на каждый mysql_connect PHP будет новый коннекшин. Естественно, что если этих коннекшинов будет море сервер буден висеть, но тут применяется обратное кэширование результатов, что прекрасно видно по тем технологиям, что тут используется, таким образом кол-во открываемых коннекшинов становится критичным только на таких страницах, как дискуссии и избранное да правка с добавлением постов. Что и прекрасно видно по работе дайриков.
Мне кажется, что вы недостаточно разбираетесь в работе связки PHP+Apache2+MySQL на уровне открытия сокетов, хранения данных, работы с памятью, иначе бы вы не утвеждали, что " вообще-то, коннекшн он один и закрывать его не надо новый запрос просто ловит этот открытый коннекшн и пользует", а так же "открывать новый connection или использовать старый - решит mySQL и php сами". Поверьте мне, я знаю о чём говорю: к моим базам данных сыпятся порядка 2000 запросов в секунду и как минимум 20% из них - на добавление данных, а ещё 30% включают в себя выборки по регулярным выражениям.
29.10.2005 в 22:54
какой смысл генерировать _всю_ ленту, если она не менялась или менялась несущественно?
29.10.2005 в 23:31
Хм... кстати, интиресно, а зачем шарашить по всей БД, когда можно писать список избранных прямо в проперти пользователя в БД. К примеру, если это всё на PHP, можно завечти отдельное поле в таблице юзера object и сторить туда PHPшный объект пользователя, содержащий всю информацию о выбранных дневниках. И потом выбирать комменты уже по этим пользователям.
Ещё интиресно, как у вас хранится информация о пользователях и их комментарии? поиск по БД можно существенно ускорить, если
а) заводить на каждый новый дневник новые таблицы, в одной из которых находится информация о пользователе, настройках дневника в другой - постинги пользователя в этот дневник
б) заводить для каждого поста отдельную таблицу комментариев, куда будут сыпатся все комменты на данный пост (разделить пост и комменты)
г) заводить новые таблицы для постов в дневник, давая им имена на основе timestamp по модулю 86400 (тобишь на каждые новые сутки - новая таблица). Тогда записи будут структуированы и по времени.
Подобная организация БД явно сократит время на шарашанье и поиск, поскольку в запросе всегда можно чётко указать в каких таблицах и что искать.
29.10.2005 в 23:53
а) заводить на каждый новый дневник новые таблицы, в одной из которых находится информация о пользователе, настройках дневника в другой - постинги пользователя в этот дневник.
б) заводить для каждого поста отдельную таблицу комментариев, куда будут сыпатся все комменты на данный пост (разделить пост и комменты)
я на тебя конкретно ахреневаю, чувак. ты видел сколько дневников здесь, сколько постов и комментариев? если ты хочешь для каждого из них создавать отдельные таблицы - то я не знаю что еще сказать 8)
а насчет того, разбираюсь ли я в программировании - я программист
чего не скажешь о некоторых... о тебе, к примеру...
тебе надо приписать букву Н после буквы M в нике.
30.10.2005 в 00:07
> б) заводить для каждого поста отдельную таблицу комментариев, куда будут сыпатся все комменты на данный пост (разделить пост и комменты)
Для случая, когда к каждому посту куча комментариев этот метод может и хорош, но для дневников не прокатит ввиду чрезмерного размножения пустых таблиц с комментами.
Кроме того, насколько мне не изменяет память, комментарии и так хранятся в отдельной таблице. Но не поручусь.
30.10.2005 в 00:18
Neiru черезмерное размножение таблиц не так страшно, сколько страшна выборка по всему, что нужно и по тому, что не нужно тоже. Если имеется возможность сократить выборку путём подставления имён нужных таблиц - тем лучше.
30.10.2005 в 00:25
и кошка у тебя на аватаре облезлая =P
30.10.2005 в 00:33
30.10.2005 в 00:38
Вы бы сами пошли на такой шаг на своём сервере? С таким подходом у вас каждый день будет появляться примерно 17000 * 3 = 51000 новых файлов на диске, большинство из которых будет даром занимать килобайт-другой.
Да и 17000 новых таблиц одинаковой структуры в базе каждый день — это тоже более чем сомнительный момент.
Прим.: 17000 - округлённое число комментариев за прошедшие сутки.
30.10.2005 в 00:38
tarkhil нафига просили я уж и не знаю...по крайней мере, надеюсь, что тред не свалится в выяснение у кого чего в куда. По крайней мере я таких бесед не поддерживаю.
30.10.2005 в 00:47
ты лучше почитай комменты других, направленные тебе.
беседу можешь не поддерживать, конечно. твое мнение насчет пары миллионов таблиц принят по назначению
30.10.2005 в 00:49
ymik т.е. на сколько я понимаю, ты хочешь устранить использование кода индексации mysql и использовать вместо него код файловой системы для поиска данных на диске?
30.10.2005 в 00:56
30.10.2005 в 01:03
Dr0n скорее задача отказаться от пересылки больших объёмов данных между серверами, чтобы не забивать канал SQL сервера, а то он вначале тратит время, чтобы отработать "тяжёлый" запрос, а потом ещё тратит время, чтобы переслать результат реквестеру (притом, что кол-во мест в очереди ограничено из-за настроек сервера, а встать в очередь до того, как не отработан предидущий запрос нельзя из-за особеностей протокола).
30.10.2005 в 01:07
30.10.2005 в 01:09
а по-моему, чрезмерное количество таблиц дает лишь много этапов в запросе. одним запросом выбрать все что нужно просто уже не удастся.