Очень низкая производительность чтения MySQL
У меня есть следующая таблица в MySQL:
CREATE TABLE tweetdb(
tweetid BIGINT(18) UNSIGNED NOT NULL,
userid INT(10) UNSIGNED NOT NULL,
timestamp CHAR(14),
tweet TEXT,
score TINYINT,
PRIMARY KEY(tweetid, userid)
) ENGINE=MYISAM PARTITION BY KEY(userid) PARTITIONS 101;
+-----------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------------+------+-----+---------+-------+
| tweetid | bigint(18) unsigned | NO | PRI | NULL | |
| userid | int(10) unsigned | NO | PRI | NULL | |
| timestamp | char(14) | YES | | NULL | |
| tweet | text | YES | | NULL | |
| score | tinyint(4) | YES | | NULL | |
+-----------+---------------------+------+-----+---------+-------+
5 rows in set (0.29 sec)
У меня есть 210 миллионов строк в этой таблице. Мой сервер Undertow (Java-приложение) отправляет GET со следующим запросом выбора:
"SELECT test.tweetdb.tweetid, test.tweetdb.tweet, test.tweetdb.score FROM test.tweetdb WHERE test.tweetdb.userid = 287543000 AND test.tweetdb.timestamp = 20140420000829;"
Я использую ID пользователя и метку времени, чтобы получить результаты, так как это только данные, которые у меня есть для тестирования базы данных. База данных предназначена только для чтения, без записи / обновления.
Я также использовал индекс на столе.
mysql> SHOW INDEX FROM tweetdb;
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tweetdb | 1 | id_index | 1 | userid | A | 1 | NULL | NULL | YES | BTREE | | |
| tweetdb | 1 | id_index | 2 | timestamp | A | 1 | NULL | NULL | YES | BTREE | | |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)
Теперь даже после использования разбиения и применения первичного ключа требуется почти 1 секунда, чтобы ответить правильным ответом, что очень долго. Мое приложение должно иметь пропускную способность не менее 6000 запросов в секунду.
Аппаратные конфигурации:
Я использую сервер Undertow (внешний интерфейс) для запроса к серверу Mysql (внутренний) на экземпляре Amazon M1.large. Чтобы избежать задержек, я запускаю оба сервера на одном экземпляре.
Может кто-нибудь мне помочь? У меня заканчиваются идеи. Спасибо!
Обновления
mysql> EXPLAIN SELECT * FROM test.tweetdb LIMIT 1;
+----+-------------+---------+------+---------------+------+---------+------+-----------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+-----------+-------+
| 1 | SIMPLE | tweetdb | ALL | NULL | NULL | NULL | NULL | 270119913 | |
+----+-------------+---------+------+---------------+------+---------+------+-----------+-------+
1 row in set (3.67 sec)
mysql> EXPLAIN SELECT * FROM test.tweetdb WHERE test.tweetdb.userid=287543000 AND test.tweetdb.timestamp=20140420000829;
+----+-------------+---------+------+---------------+------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+---------+-------------+
| 1 | SIMPLE | tweetdb | ALL | NULL | NULL | NULL | NULL | 2657601 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+---------+-------------+
1 row in set (0.00 sec)
Время с внешнего сервера Undertow
1 ответ
Ваш первичный ключ - это сочетание tweetid и userid. И для mysql это происходит для полного поиска, потому что ваша таблица имеет первичный ключ столбца combile. Вы можете создать другой ключ, используя только ID пользователя. Для mysql, если у вас есть два столбца в ключе, тогда они должны присутствовать там, где в противном случае он считает это для поиска всей таблицы