2015-03-31 4 views
0

je le tableau suivant MySQL:très lent MySQL Lire Performance

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) 

Je 210 millions de lignes dans ce tableau. Mon serveur Undertow (application java) envoie une requête GET avec la requête de sélection suivante:

"SELECT test.tweetdb.tweetid, test.tweetdb.tweet, test.tweetdb.score FROM test.tweetdb WHERE test.tweetdb.userid = 287543000 AND test.tweetdb.timestamp = 20140420000829;" 

J'utilise l'ID utilisateur et horodatage pour obtenir les résultats car il est que les données dont je dispose pour tester la base de données. La base de données est à des fins de lecture seule, sans écritures/mises à jour.

J'ai également utilisé un index sur la table.

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) 

Maintenant, même après avoir utilisé le partitionnement et l'application d'une clé primaire, il faut presque 1 seconde pour répondre de retour avec une réponse correcte, ce qui est très long. Mon application doit avoir un débit d'au moins 6000 requêtes par seconde.

Configurations matérielles:

Je cours un serveur Undertow (frontal) pour interroger le serveur Mysql (back-end) sur une instance Amazon M1.large. Pour éviter la latence, j'exécute les deux serveurs sur la même instance.

Quelqu'un peut-il m'aider? Je manque d'idées. Merci!

Mises à jour

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) 

Temps du serveur frontend Undertow

The time it takes is 1.3 seconds

+0

Que dit 'explain select ...'? –

+0

Mise à jour de la question. – AngryPanda

+0

Cela signifie qu'il n'est pas nécessaire d'utiliser un index pour ajouter un index comme 'alter table test.tweetdb ajouter un index user_timestamp_idx (userid, timestamp)' –

Répondre

0

Votre clé primaire est une combinaison de tweetid et userid. Et pour mysql ça va pour une recherche complète car votre table a la clé primaire de la colonne combile. Vous pouvez créer une autre clé n'ayant que l'ID utilisateur. Pour mysql Si vous avez deux colonnes dans la clé alors elles devraient être présentes là où autrement elle le considère pour la recherche de table entière

+0

Dans mon jeu de données, la combinaison userid et timestamp n'est pas unique. Un twitterbot peut créer plusieurs tweets en même temps. Je voulais créer une clé primaire sur tweetid, userid et timestamp mais cela prend beaucoup de temps pour charger les données dans la table. Recommandez-vous que je lâche la clé primaire tous ensemble? – AngryPanda