2009-06-25 9 views
2

plus rapide que je suis en train de créer une requête plus rapide, à droite j'ai maintenant de grandes bases de données. Mes tailles de table sont 5 cols, 530k rangs, et 300 cols, 4k rangs (malheureusement je n'ai aucun contrôle sur l'architecture, sinon je n'aurais pas ce problème idiot avec un mauvais db).Création d'un MySQL Query

SELECT cast(table2.foo_1 AS datetime) as date, 
     table1.*, table2.foo_2, foo_3, foo_4, foo_5, foo_6, foo_7, foo_8, foo_9, foo_10, foo_11, foo_12, foo_13, foo_14, foo_15, foo_16, foo_17, foo_18, foo_19, foo_20, foo_21 
FROM table1, table2 
WHERE table2.foo_0 = table1.foo_0 
     AND table1.bar1 >= NOW() 
     AND foo_20="tada" 
ORDER BY 
     date desc 
LIMIT 0,10 

J'ai répertorié les table2.foo_0 et table1.foo_0 ainsi foo_20 dans l'espoir que cela permettrait plus rapide des requêtes .. je suis toujours à près de 7 secondes le temps de chargement .. est-il autre chose que je peut faire?

Vive

+0

300 colonnes ...? –

+0

comme je l'ai dit, 0 contrôle, et oui horriblement architecturé :( – Petrogad

+0

Êtes-vous familier avec la commande EXPLAIN http://dev.mysql.com/doc/refman/5.1/en/using-explain.html – Eli

Répondre

3

Je pense un index sur bar1 est la clé. Je rencontre toujours des problèmes de performances avec les dates car il doit comparer chacune des 530K lignes.

+0

astuce. – Petrogad

0

table2 a besoin d'un indice composé sur foo_0, foo_20 et bar1.

1

L'indexation table1.bar1 peut améliorer la> = comparaison MAINTENANT. Un indice composé sur table2.foo_0 et table2.foo_20 aidera. Un index sur table2.foo_1 peut aider le tri. Dans l'ensemble, le fait de coller la sortie de votre requête avec le préfixe EXPLAIN peut également donner quelques indications.

0

Un index sur table1.foo_0, table1.bar1 pourrait aussi aider, en supposant que foo_20 appartient à Table1.

Voir How to use MySQL indexes et Optimizing queries with explain.

Utilisez des index composés correspondant à vos égalités WHERE (en général la colonne la plus à gauche de l'index), WHERE à la valeur abolue (middle) et ORDER BY (à droite, dans le même ordre).

2

Créer les indices suivants:

CREATE INDEX ix_table1_0_1 ON table1 (foo_1, foo_0) 
CREATE INDEX ix_table2_20_0 ON table2 (foo_20, foo_0) 

et Rewrite requête comme ceci:

SELECT cast(table2.foo_1 AS datetime) as date, 
     table1.*, table2.foo_2, foo_3, foo_4, foo_5, foo_6, foo_7, foo_8, foo_9, foo_10, foo_11, foo_12, foo_13, foo_14, foo_15, foo_16, foo_17, foo_18, foo_19, foo_20, foo_21 
FROM table1 
JOIN table2 
ON  table2.foo_0 = table1.foo_0 
     AND table2.foo_20 = "tada" 
WHERE table1.bar1 >= NOW() 
ORDER BY 
     table1.foo_1 DESC 
LIMIT 0, 10 

Le premier indice sera utilisé pour ORDER BY, le second sera utilisé pour JOIN.

Vous, cependant, peuvent tirer profit de la création du premier indice comme celui-ci:

CREATE INDEX ix_table1_0_1 ON table1 (bar, foo_0) 

qui peuvent appliquer un filtrage plus restrictive sur bar.

J'ai un billet de blog sur ce point:

, qui conseille sur la façon de choisir l'index pour créer des cas comme ça.