Очень низкая производительность чтения 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,3 секунды

1 ответ

Ваш первичный ключ - это сочетание tweetid и userid. И для mysql это происходит для полного поиска, потому что ваша таблица имеет первичный ключ столбца combile. Вы можете создать другой ключ, используя только ID пользователя. Для mysql, если у вас есть два столбца в ключе, тогда они должны присутствовать там, где в противном случае он считает это для поиска всей таблицы

Другие вопросы по тегам