Допустим есть таблица mysql содержащая личные сообщения пользователей. При загрузке страницы первый запрос выбирает все сообщения определенного пользователя. Остальные запросы будут передаваться ajax-сом с интервалом например в 5 секунд (чтоб определить наличие новых сообщений). Как оптимальнее будет выполнить запрос к таблице, чтобы максимально уменьшить нагрузку на сервер: 1. Постоянно отправлять запрос ко всем сообщениям пользователя. (и обноявлять их на странице) 2. Отправлять запрос только к новым-непрочитанным сообщениям (и выводить их ниже старых (уже отображенных на странице сообщений)) Естественно во втором случае не придется постоянно обновлять все сообщения на странице, т.к. новых сообщений как правило очень мало. Какой вариант лутше для сервера и пользователей?? Или для оптимальности не зависит сколько сервер выдает результатов??? Хотелось бы услышать мнение многих знающих людей.
> Как оптимальнее будет выполнить запрос к таблице, чтобы максимально уменьшить нагрузку на сервер: 1) Чем меньше размер данных, тем лучше. 2) Запрос только по ключу - тысячные доли секунды на миллионах записей. Наилучшее - первичный ключ. 3) Поставьте sql_cache в запрос и MySQL-сервер потянет 5000+ AJAX запросов в секунду при условии, что таблица обновляется раз в пару-другую секунд. (в 5-10 раз быстрее, чем пункт 2) 4) дальнейшее уменьшение нагрузки - использовать внешний кеш.
Спасибо за ответы, уже накалякал код №2, вроде работает, но есть несколько вопросов по посту Chushkin 3 и 4 пункты отпадают, т.к. пользователей пока мало, а может и не будет вообще (если грамотно код не сделаю) Вопрос по номеру 2 "Запрос только по ключу" - "Наилучшее - первичный ключ" И еще "И не забудьте создать индексы" Я в этом ничего не понимаю, поэтому прошу помощи. У меня вот такая таблица Код (Text): CREATE TABLE IF NOT EXISTS `pm` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `sender_id` int(10) DEFAULT NULL, `receiver_id` int(10) NOT NULL, `date` int(10) unsigned NOT NULL, `read_at` int(10) unsigned NOT NULL, `body` text NOT NULL, `status` varchar(9) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
просто сообщай номер последнего сообщения, которое у тебя есть. Добавлено спустя 27 секунд: первичный ключ
понятно, теперь насчет индексов: При добавлении одного сообщения в БД добавляется такая запись Код (Text): (1, 2, 10, 1371918306, 0, 'Текст', 'noread'), (2, 10, 2, 1371918306, 0, 'Текст', 'noread'), Если при запросе у меня такой код: Код (Text): p.id, p.body, p.date FROM pm AS p WHERE p.sender_id='.$my['id'].' AND p.receiver_id='.$user_id.' ORDER BY p.date ASC Как правильно выставить индексы, у меня на уме вот так: Код (Text): KEY `sender_id` (`sender_id`), KEY `receiver_id` (`receiver_id`), KEY `status` (`status`) Очередность как-нибудь влияет на производительность? Или вообще не правильно?
Это плохо "Учите матчасть и Вам воздастся". В идеале создайте ключ, в котором есть все поля используемые в WHERE. Вероятно в Вашем случае минимально нужны индексы key(sender_id, id) и key(receiver_id, id), хотя точно сложно сказать, не зная запросов. По поводу PRIMARY igordata сказал. И по поводу моего п.3 повторюсь: sql_cache вредит только если какая-либо таблица запросе часто изменяется, иначе "кашу маслом не испортишь" - ставьте. Добавлено спустя 4 минуты 2 секунды: Для запроса с "WHERE p.sender_id='.$my['id'].' AND p.receiver_id='.$user_id.' ORDER BY p.date ASC"... Для максимума скорости и минимум нагрузки создайте ключ: key(sender_id, receiver_id) Добавлено спустя 2 минуты 15 секунд: Кроме того, внемлите igordata и тогда будет по Вапшему п.2 - догружать не имеющееся на странице. Это будет быстрее и меньше нагружать сервер, как и сказано выше.
Представляю, что будет когда будет 1000.000 человек. Нужно делать какие то особые проверки, что пользователь действительно на сайте, когда открыт сайт, а пользователь ничего не делает, он будет слать и слать... Я открыл и пошел фильм смотреть, а у меня все шлет и шлет... Думаю лучше будет воспользоваться серверным языком "JavaScript" и принимать со стороны сервера и отдавать пользователю без перезагрузки, только тогда, когда действительно ему отправили письмо... Либо писать свою мини платформу.
Ajax будет слать запросы только когда открыта переписка с конкретным пользователем. Не думаю, что все из 1000 пользователей одновременно откроют переписку будут на нее смотреть, а потом пойдут фильм смотреть. Надеюсь сервер выдержит... В нете почитал насчет того, чтоб "принимать со стороны сервера и отдавать пользователю без перезагрузки, только тогда, когда действительно ему отправили письмо", но достойного примера так и не нашел, как я понял у людей проблемы с этим делом, толком не работает
делай на аяксе. когда у тебя будет 1000 онлайн - возьмешь машину по-сильнее. когда будет 100 000 онлайн =) переделаете всё.