2011-01-20 6 views
3

Un nouveau projet sur lequel nous travaillons nécessite beaucoup d'analyse de données mais nous trouvons que c'est TRÈS lent, nous cherchons des moyens de changer notre approche avec le logiciel et/ou le matériel.Massive DB et mysql

Nous courons actuellement sur une instance amazon EC2 (linux):

High-CPU Extra Large Instance 

7 GB of memory 
20 EC2 Compute Units (8 virtual cores with 2.5 EC2 Compute Units each) 
1690 GB of instance storage 
64-bit platform 
I/O Performance: High 
API name: c1.xlarge 


processor  : 7 
vendor_id  : GenuineIntel 
cpu family  : 6 
model   : 26 
model name  : Intel(R) Xeon(R) CPU   E5506 @ 2.13GHz 
stepping  : 5 
cpu MHz   : 2133.408 
cache size  : 4096 KB 

MemTotal:  7347752 kB 
MemFree:  728860 kB 
Buffers:   40196 kB 
Cached:  2833572 kB 
SwapCached:   0 kB 
Active:  5693656 kB 
Inactive:  456904 kB 
SwapTotal:   0 kB 
SwapFree:   0 kB 

Une partie de la db est des articles et des entités et une table de lien par exemple:

mysql> DESCRIBE articles_entities; 
+------------+--------------+------+-----+---------+-------+ 
| Field  | Type   | Null | Key | Default | Extra | 
+------------+--------------+------+-----+---------+-------+ 
| id   | char(36)  | NO | PRI | NULL |  | 
| article_id | char(36)  | NO | MUL | NULL |  | 
| entity_id | char(36)  | NO | MUL | NULL |  | 
| created | datetime  | YES |  | NULL |  | 
| modified | datetime  | YES |  | NULL |  | 
| relevance | decimal(5,4) | YES | MUL | NULL |  | 
| analysers | text   | YES |  | NULL |  | 
| anchor  | varchar(255) | NO |  | NULL |  | 
+------------+--------------+------+-----+---------+-------+ 
8 rows in set (0.00 sec) 

Comme vous pouvez voir du tableau ci-dessous nous avons beaucoup d'assoications croissance à un taux de 100 000+ par jour

mysql> SELECT count(*) FROM articles_entities; 
+----------+ 
| count(*) | 
+----------+ 
| 2829138 | 
+----------+ 
1 row in set (0.00 sec) 

Une simple requête comme celui ci-dessous prend trop de temps (12 secondes)

mysql> SELECT count(*) FROM articles_entities WHERE relevance <= .4 AND relevance > 0; 
+----------+ 
| count(*) | 
+----------+ 
| 357190 | 
+----------+ 
1 row in set (11.95 sec) 

Que devrions-nous envisager d'améliorer notre temps de consultation? Différents espaces de stockage DB Matériel différent.

+0

Votre table est-elle indexée correctement? –

+0

N'est-ce pas évident à partir de la décharge de table fourni? – Lizard

+0

MyISAM ou InnoDB table, MyIsam est beaucoup plus rapide .. – B4NZ41

Répondre

1

Il y a trois choses qui comptent en ce qui concerne les performances des requêtes:

index. Mémoire. Tout le reste.

La première chose à faire est de vérifier vos index. Faites un EXPLAIN sur vos requêtes pour découvrir comment MySQL les traite.

Si cela semble raisonnable, la prochaine chose serait de vérifier la mémoire. Quelle est la taille de votre base de données totale? La mémoire est bon marché ces jours-ci, et les requêtes qui s'exécutent à partir de la mémoire seront beaucoup, beaucoup plus rapide que les requêtes qui doivent lire à partir du disque. Après avoir exploré ceux-ci, si les performances sont encore lentes, il est peut-être temps d'envisager d'autres options.

+0

Yup tout ce qui précède fait, d'où la question, pouvez-vous offrir des pointeurs? – Lizard

+0

Même avant de discuter des index, nous devons connaître les E/S disque. Pour la requête qui a duré 12 secondes, combien de disques i/os at-il pris? Quelle était la stratégie de requête utilisée par le SGBD? Était-ce un scan de table complet? De là, nous pouvons aller à la stratégie de l'index. –

2

L'utilisation de char (36) pour les clés n'est pas la plus rapide que vous pouvez faire avec MySQL. Utilisez INT-types pour les clés si possible. Si vous indexez les colonnes CHAR, les indices seront très importants par rapport à un (BIG) index INT (sinon « correctement » créé)

Toutefois, si vos valeurs de la colonne ne sont pas numériques, vous êtes coincé avec des colonnes CHAR (qui ARE est toujours plus rapide que VARCHAR, mais peut créer des index volumineux).

Veuillez fournir un SHOW CREATE TABLE de tables pour voir les paramètres de clé/index, et aussi comme la réponse précédente a dit, un EXPLAIN pour les questions en question pourrait aider à fournir une meilleure réponse.

PS. Utilisez SHOW TABLE STATUS LIKE '{table_name}' pour voir les tailles d'index (et de données) de la table.

3

Comme mrorigo demandé, s'il vous plaît fournir le SHOW CREATE TABLE articles_entities afin que nous puissions voir les index réels de votre table.

Comme une note de la documentation MySQL http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html

If the table has a multiple-column index, any leftmost prefix of the index can be used by the optimizer to find rows. 
For example, if you have a three-column index on (col1, col2, col3), you have indexed search capabilities on (col1), (col1, col2), and (col1, col2, col3). 

MySQL cannot use an index if the columns do not form a leftmost prefix of the index

Donc, si relevance fait partie d'un index à plusieurs colonnes, mais n'est pas la colonne de gauche de cet indice, l'indice ne sert pas à votre requête .

Ceci est un problème commun qui est souvent négligé.