За последние 24 часа нас посетили 60163 программиста и 1744 робота. Сейчас ищут 1083 программиста ...

Какой запрос оптимальнее для сервера

Тема в разделе "MySQL", создана пользователем skillful, 22 июн 2013.

  1. skillful

    skillful Активный пользователь

    С нами с:
    30 ноя 2010
    Сообщения:
    73
    Симпатии:
    0
    Допустим есть таблица mysql содержащая личные сообщения пользователей.
    При загрузке страницы первый запрос выбирает все сообщения определенного пользователя.

    Остальные запросы будут передаваться ajax-сом с интервалом например в 5 секунд (чтоб определить наличие новых сообщений).

    Как оптимальнее будет выполнить запрос к таблице, чтобы максимально уменьшить нагрузку на сервер:

    1. Постоянно отправлять запрос ко всем сообщениям пользователя. (и обноявлять их на странице)
    2. Отправлять запрос только к новым-непрочитанным сообщениям (и выводить их ниже старых (уже отображенных на странице сообщений))

    Естественно во втором случае не придется постоянно обновлять все сообщения на странице, т.к. новых сообщений как правило очень мало.

    Какой вариант лутше для сервера и пользователей?? Или для оптимальности не зависит сколько сервер выдает результатов???
    Хотелось бы услышать мнение многих знающих людей.
     
  2. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    Надо из базы брать ровно столько сколько нужно для работы.
     
  3. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    > Как оптимальнее будет выполнить запрос к таблице, чтобы максимально уменьшить нагрузку на сервер:
    1) Чем меньше размер данных, тем лучше.
    2) Запрос только по ключу - тысячные доли секунды на миллионах записей. Наилучшее - первичный ключ.
    3) Поставьте sql_cache в запрос и MySQL-сервер потянет 5000+ AJAX запросов в секунду при условии, что таблица обновляется раз в пару-другую секунд. (в 5-10 раз быстрее, чем пункт 2)
    4) дальнейшее уменьшение нагрузки - использовать внешний кеш.
     
  4. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    Мда уж, не написал главного я за 2 вариант :)
     
  5. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Естественно второй, если оба запроса оптимальны. И не забудьте создать индексы.
     
  6. skillful

    skillful Активный пользователь

    С нами с:
    30 ноя 2010
    Сообщения:
    73
    Симпатии:
    0
    Спасибо за ответы, уже накалякал код №2, вроде работает, но есть несколько вопросов по посту Chushkin

    3 и 4 пункты отпадают, т.к. пользователей пока мало, а может и не будет вообще (если грамотно код не сделаю)
    Вопрос по номеру 2 "Запрос только по ключу" - "Наилучшее - первичный ключ"
    И еще "И не забудьте создать индексы"
    Я в этом ничего не понимаю, поэтому прошу помощи. У меня вот такая таблица
    Код (Text):
    1. CREATE TABLE IF NOT EXISTS `pm` (
    2.   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    3.   `sender_id` int(10) DEFAULT NULL,
    4.   `receiver_id` int(10) NOT NULL,
    5.   `date` int(10) unsigned NOT NULL,
    6.   `read_at` int(10) unsigned NOT NULL,
    7.   `body` text NOT NULL,
    8.   `status` varchar(9) NOT NULL,
    9.   PRIMARY KEY (`id`)
    10. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
     
  7. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    просто сообщай номер последнего сообщения, которое у тебя есть.

    Добавлено спустя 27 секунд:
    первичный ключ
     
  8. skillful

    skillful Активный пользователь

    С нами с:
    30 ноя 2010
    Сообщения:
    73
    Симпатии:
    0
    понятно, теперь насчет индексов:
    При добавлении одного сообщения в БД добавляется такая запись
    Код (Text):
    1. (1, 2, 10, 1371918306, 0, 'Текст', 'noread'),
    2. (2, 10, 2, 1371918306, 0, 'Текст', 'noread'),
    Если при запросе у меня такой код:
    Код (Text):
    1. 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):
    1.  
    2.   KEY `sender_id` (`sender_id`),
    3.   KEY `receiver_id` (`receiver_id`),
    4.   KEY `status` (`status`)
    Очередность как-нибудь влияет на производительность? Или вообще не правильно?
     
  9. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Это плохо :(
    "Учите матчасть и Вам воздастся".

    В идеале создайте ключ, в котором есть все поля используемые в 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 - догружать не имеющееся на странице. Это будет быстрее и меньше нагружать сервер, как и сказано выше.
     
  10. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Представляю, что будет когда будет 1000.000 человек.
    Нужно делать какие то особые проверки, что пользователь действительно на сайте, когда открыт сайт, а пользователь ничего не делает, он будет слать и слать... Я открыл и пошел фильм смотреть, а у меня все шлет и шлет...
    Думаю лучше будет воспользоваться серверным языком "JavaScript" и принимать со стороны сервера и отдавать пользователю без перезагрузки, только тогда, когда действительно ему отправили письмо...
    Либо писать свою мини платформу.
     
  11. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
  12. skillful

    skillful Активный пользователь

    С нами с:
    30 ноя 2010
    Сообщения:
    73
    Симпатии:
    0
    Ajax будет слать запросы только когда открыта переписка с конкретным пользователем. Не думаю, что все из 1000 пользователей одновременно откроют переписку будут на нее смотреть, а потом пойдут фильм смотреть. Надеюсь сервер выдержит...

    В нете почитал насчет того, чтоб "принимать со стороны сервера и отдавать пользователю без перезагрузки, только тогда, когда действительно ему отправили письмо", но достойного примера так и не нашел, как я понял у людей проблемы с этим делом, толком не работает
     
  13. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    делай на аяксе. когда у тебя будет 1000 онлайн - возьмешь машину по-сильнее. когда будет 100 000 онлайн =) переделаете всё.
     
  14. skillful

    skillful Активный пользователь

    С нами с:
    30 ноя 2010
    Сообщения:
    73
    Симпатии:
    0
    Прям мысли читаешь :)