2010-07-20 4 views
3

Я запускаю сервер, который убивается количеством запросов, которые он получает от одной из наших игр для iPhone, для хранения баллов. Под этим я подразумеваю, что сервер становится невосприимчивым.SELECT/UPDATE и SELECT/INSERT убивают сервер MySQL

Я действительно знаю достаточно MySQL/PHP, чтобы пройти, поэтому я барахтаюсь в своих попытках исправить это. Я уверен, что это проблема, которая может быть оптимизирована, потому что у нас есть выделенный сервер. Мы обрабатываем только 300 запросов в минуту.

В основном мы проверяем счет, который кто-то отправляет из своей игры в iPhone (используя SELECT), чтобы узнать, есть ли у них существующий счет. Если они это сделают, и их новый балл лучше, мы делаем ОБНОВЛЕНИЕ, иначе мы делаем INSERT.Высказывания выглядеть следующим образом:

$ SQL = «SELECT ID, оценка, уровень FROM $ таблицы WHERE платы = '$ доска' И имя = '$ имя' AND UDID = '$ UDID' И fbuid = ' $ fbuid '

Операторы UPDATE и INSERT выглядеть следующим образом:

$ SQL = "UPDATE $ таблица SET балл = '$ бальной', уровень = '$ уровня', страна =' $ country ', date = CURRENT_TIMESTAMP WHERE board =' ​​$ board 'AND name =' $ name 'AND udid =' $ udid 'И fbuid =' $ fbuid '"

$ sql = "INSERT INTO $ table (board, udid, fbuid, name, score, level, country) VALUES ('$ board', '$ udid', '$ fbuid', '$ name', '$ score ' '$ уровне', $ страна')»

И для полноты картины, вот определение для таблицы:

CREATE TABLE $table (
id INT (11) NOT NULL AUTO_INCREMENT ,
board tinyint (4) NOT NULL,
udid varchar (45) по умолчанию NULL, то
fbuid BIGINT (20) без знака по умолчанию NULL, то
name VARCHAR (25) по умолчанию NULL, то
country TINYINT (4) по умолчанию NULL, то
level TINYINT (4) по умолчанию NULL, то
score десятичное (10,0) по умолчанию NULL,
date метка NOT NULL CURRENT_TIMESTAMP по умолчанию,
PRIMARY KEY (id)
KEY scoreidx (score),
КЛЮЧ udididx (udid),
КЛЮЧ fbuididx (fbuid),
КЛЮЧ boardidx (board),
КЛЮЧ levelidx (level),
КЛЮЧ countryidx (country)
) ДВИГАТЕЛЬ = MyISAM УМОЛЧАНИЮ CHARSET = latin1

В настоящее время я подключаюсь к серверу MySQL с PHP, используя:

$ conn = mysql_pconnect (DB_HOST, DB_USER, DB_PASSWORD, MYSQL_CLIENT_INTERACTIVE);

Но использовался ранее для использования msql_connect, но не заметил улучшения с этим.

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

ответ

4

В MyISAM вместо настольных замков InnoDB установлены столовые замки. Вы можете создать копию своей таблицы, изменить движок на InnoDB и (на тестовом сервере) проверить нагрузку с помощью mysqlslap или аналогичных инструментов стресс-тестирования.

Кроме того, очень важно:

ALTER TABLE tablename ADD INDEX(board,name,udid,fbuid) 

MySQL может использовать только 1 индекс в то время, так что ваши несколько «свободные» те не делают, что очень хорошо, когда всегда запрашивая для этой конкретной комбинации.

+0

Большое спасибо. Сегодня утром я преобразовал таблицу в InnoDB и добавил индекс, который вы предложили. Стоит ли удалять некоторые другие индексы, которые я положил, думая, что они помогают инструкции SELECT, но, похоже, не используются? Потому что я предполагаю, что для обновления индексов требуется время. – mmopy

+0

Это зависит от ваших других запросов/требований. Если у вас есть предложения 'WHERE' или' JOIN ... ON' в запросах, которые выбираются исключительно на основе одного столбца, стоит сохранить индекс в этом отдельном поле. Если нет, вы можете ускорить вставку/обновление, отбросив их. – Wrikken

1

«MySQL использует блокировку на уровне таблицы для MyISAM, память и MERGE таблицы, страницу блокировки на уровне для таблиц BDB и блокировки на уровне строк для таблиц InnoDB.»

http://dev.mysql.com/doc/refman/5.0/en/internal-locking.html

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

0

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

$sql = "INSERT INTO $table(board, udid, fbuid, name, score, level, country) VALUES 
('$board', '$udid', '$fbuid', '$name', '$score', '$level', $country') ON DUPLICATE KEY 
UPDATE score = '$score'"; 
+0

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

+1

Мне нравится использовать PDO, но выбор интерфейса практически не влияет на производительность взаимодействия с базой данных. –

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