2016-07-29 21 views
2

Ich muss eine Abfrage für eine Tabelle ausführen, wo es mehr als 10 Millionen Zeilen gibt. Die Tabellenstruktur istIndizierung für mehrere Spalten

user(varchar 100), 
played(int 11), 
won(int 11), 
lost(int 11), 
drawn(int 11), 
user1(varchar 30), 
user2(varchar 30). 


Where 
User - primary key 
user1 - index 
user2 - index 

MySql Datenbank-Engine MyISAM ist.

Mein Problem ist - Wenn ich die unten Abfrage ausführen dauert es mehr als 17 Sekunden.

SELECT * FROM h2hstats 
WHERE (won+lost+drawn) > 5 
    AND (user1 = '717054941' OR user2 = '717054941') 

Wie kann ich diese Ausführungszeit reduzieren?

Wird ich eine weitere Indizierung auf (Won + Lost + Drawn) Spalten vornehmen?

+0

Nein, weil sie sie nicht suchen. Sobald die Bedingung erfüllt ist, haben Sie Zugriff auf die Daten. Es kommt also auf die richtige Indizierung für user1 und user2 an. Und die Verwendung numerischer Feldtypen (INTEGER oder BIGINT) für Spalten, die nur numerische Werte enthalten, wird ebenfalls die Leistung verbessern. – syck

+1

hat noch nie so funktioniert, aber vielleicht so: AND 717054941 IN (user1, user2) – Jeff

+0

Ich empfehle, errechneten Index auf win + last + gezeichnet ..http: //dev.mysql.com/doc/refman/5.7 /en/generated-column-index-optimizations.html..weitere bin ich nicht sicher, wie zwei separate Indizes (user1, user2) verwendet werden können – TheGameiswar

Antwort

2

Wenn die Benutzerspalten Zahlen sind, verwenden Sie keine einfachen Anführungszeichen für die Konstanten. Dies kann den Optimierer verwirren. Dies wird wahrscheinlich nicht Ihre Abfrage helfen (My SQL macht eine schlechte Arbeit mit Indizes für OR), aber es ist einen Versuch wert.

Als nächstes betrachten Sie die Abfrage als Umschreiben:

SELECT * 
FROM h2hstats 
WHERE (won + lost + drawn) > 5 AND user1 = 717054941 
UNION ALL 
SELECT * 
FROM h2hstats 
WHERE (won + lost + drawn) > 5 AND user2 = 717054941 ; 

MySQL definitiv Indizes für jede der Unterabfragen verwenden. Das sollte einen Leistungsschub bringen.

(Hinweis: Diese Version geht davon aus, dass user1 <>user2 Wenn dies möglich ist, Sie UNION anstatt UNION ALL verwenden möchten..)

Verwandte Themen