2010-07-30 2 views
0

Я работаю над этой игрой под названием «Крепость», расположенной по адресу http://www.joemajewski.com/fortress. В любом случае, это одна из тех ролевых игр на основе браузера, где игроки создают армию и обновляют свою статистику, чтобы получить высокий рейтинг в таблице лидеров.Выполнение 100+ запросов на обновление MySQL. Советы по оптимизации Please :)

Каждые 30 минут будет выполняться задание cron, которое производит некоторые обновления. Он проходит через каждого игрока в игре (который будет продолжать расти естественно с течением времени по мере того, как все больше людей присоединятся) и обновляет определенную статистику. Это дает каждому 1 дополнительный оборот, дает им золото на основе их дохода, продуктов питания, дерева, меди, железа и т. Д., А также обновляет их рейтинг.

Это все mumbo-jumbo, я знаю, но дело в том, что каждый игрок будет иметь свой собственный запрос на обновление. Я приуроченные сценарий только с тремя членами: время

исполнения с функцией mysql_query() закомментированными для обновлений: ~ 3,5 мс

время выполнения с функцией mysql_query() работает правильно: ~ 14 мс

Очевидно, что запросы обновления, которые приведут к тому, что мое задание cron будет очень медленным, как только в игре будет зарегистрировано более 100 зарегистрированных участников. Я надеюсь, что у вас будет 100 активных игроков в течение двух недель после запуска игры, но многие игроки создают несколько учетных записей, поэтому я ожидаю по меньшей мере 200 участников через пару недель. С 200 запросами обновления, а также дополнительным временем для сортировки участников и расчета ранжирования, вероятно, потребуется 2 секунды для запуска задания cron.

Мой вопрос к вам. Есть ли более быстрый способ сделать что-то подобное? Я попытался добавить запросы «НАЧАТЬ ПЕРЕДАЧУ» и «КОМИТЕТ» до и после цикла, соответственно, но трудно оценить скорость всего с тремя членами. Будут ли транзакции сделать сценарий лучше или хуже? Любые другие способы обойти это? Любая помощь будет оценена по достоинству.

Большое спасибо за то, что нашли время, чтобы послушать мою просьбу.

+2

Необходимо увидеть запросы ... –

+0

индексы, индексы, индексы –

+0

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

ответ

4

Основываясь на ограниченных деталях в вопросе, похоже, что вы можете делать все обновления игроков в одном запросе или в нескольких запросах, а не перебирать их по отдельности.

Рассмотрите возможность добавления поворотов и обновления их золота на основе формулы, все в одном запросе, который влияет на всю таблицу.

т.е. в качестве основного упрощением:

update Players set turns = turns + 1, 
        gold = (gold + (income * 100) + (wood * 25) + (copper * 25)) 

ли эта помощь ?.

Что касается ранжирования, каким образом вы рассчитываете его прямо сейчас?

+0

Мне очень нравится эта идея. Многие из переменных в обновлении очень сложны, и запрос будет огромным по размеру. Я никогда не думал о том, чтобы делать это таким образом, но это сделало бы игру практически безграничной с точки зрения количества участников. На данный момент я могу сохранить его так, как он есть, поскольку для выполнения всех обновлений было бы огромным инвестированием времени, чтобы работать с одним запросом, и это всегда то, что я могу реализовать после того, как игра уже запущена (при необходимости быть, я знаю?). –

+0

Не говоря уже о том, что игра завершена на 75%, и вчера я потратил все, чтобы оптимизировать заголовок и прочее, и сделал его на 15% быстрее, сократив 5 или около того запросов в один запрос, который захватил все необходимое. –

+0

Как насчет того, чтобы сообщить мне, когда это будет сделано, чтобы я мог играть? [email protected] – Fosco

1

Мое предложение состояло в создании тестовой среды. Затем заполните эту тестовую среду тысячами строк пользовательских данных. Чтобы понять, сколько данных ввести, я использую эмпирическое правило ((What You Expect) + (What You Hope For)) * 2. Поэтому, если вы искупите 100 пользователей и надеетесь (реальная надежда) получить 5000, вы должны протестировать, по крайней мере, 10200 пользователей ...

Итак, создайте большую базу данных и постарайтесь быть максимально реалистичными, но Не трать слишком много энергии на это. Как только вы там, попробуйте свои запросы по одному. Оптимизируйте каждый. Затем создайте простой PHP-скрипт для выполнения ряда запросов при разных задержках (query1, sleep 50ms, query2, sleep 100ms, query3, query4, sleep 100ms, etc). Затем используйте инструмент, например, ab (Apache Bench), чтобы выполнить этот скрипт и искать проблемы в db (помните, задача здесь - подчеркнуть БД, поэтому, если это не напрягается, продолжайте толкать, пока это не произойдет).

+0

Мне нравится этот подход. Как только я буду ближе к завершению, я еще раз перейду от кодирования и снова буду работать над оптимизацией. Я выложу большое количество ненужных данных в таблицы и узнаю, какие запросы меня замедляют. Я потратил всю вчерашнюю оптимизацию, добавив индексы, и я перешел к одному запросу, чтобы захватить все необходимые данные для игрока. На регулярной загрузке страницы всего 3 запроса: (1) Один для получения метаданных для страницы, которая выполняется независимо от того, что. (2) Другой получает данные пользователя, как сказано выше. Только для зарегистрированных пользователей. (3) Последние обновления счетчика хитов, протоколирует IP, время загрузки –

+0

Очень хорошо. Помните: «Преждевременная оптимизация - это корень всего зла». Сначала запустите его. Тогда волнуйтесь об оптимизации всего. В конце концов, то, что сегодня кажется узким местом, может быть микро-оптимизацией на следующей неделе (или даже не может закончиться в последней кодовой базе из-за рефакторов по другим причинам) ... – ircmaxell

+0

Ха-ха, слова для жизни. –

0

Вы ошибаетесь.

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

Хранить в последний раз, когда были рассчитаны данные (lt).

количества ресурсов теперь: г2 = г + д-р * (теперь-л), где
др - изменение ресурсов во время сейчас - время л - время, когда был сделан в прошлом г Сохранить в базу данных. r - количество ресурсов, хранящихся в db r2 - количество ресурсов в настоящее время

Вам даже не нужно обновлять таблицу каждый раз, просто прочитайте r, dr, lt из базы данных, вычислите r2 сейчас.

Выполняя этот путь, вы получите ресурсы в реальном времени, и у вас нет рабочих мест.

+0

+1 Мне тоже нравится этот подход, но он, вероятно, не будет работать во всех случаях. Рейтинги могут стать довольно неустойчивыми на основе бездействия. – Fosco

+0

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

+0

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

Смежные вопросы