2009-06-25 13 views
2

Ich versuche, eine schnellere Abfrage zu erstellen, jetzt habe ich große Datenbanken. Meine Tabellengrößen sind 5 col, 530k Zeilen und 300 col, 4k Zeilen (leider habe ich keine Kontrolle über die Architektur, sonst hätte ich dieses dumme Problem nicht mit einer schlechten db).Erstellen einer schnelleren MySQL-Abfrage

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 

ich indiziert habe den table2.foo_0 und table1.foo_0 zusammen mit foo_20 in der Hoffnung, dass es für eine schnelleren Abfragen erlauben würde .. ich bin bei noch fast 7 Sekunden Ladezeit .. ist es mir etwas anderes tun können?

Prost

+0

300 Spalten ...? –

+0

wie ich schon sagte, 0 Kontrolle, und ja schrecklich Architected :( – Petrogad

+0

Kennen Sie den Befehl EXPLAIN? Http://dev.mysql.com/doc/refman/5.1/en/using-explain.html – Eli

Antwort

3

Ich denke, ein Index auf bar1 ist der Schlüssel. Ich stoße immer auf Leistungsprobleme mit Daten, weil es jede der 530K Zeilen vergleichen muss.

+0

Das tat die Trick, Prost! – Petrogad

0

table2 benötigt eine Verbindung Index auf foo_0, foo_20 und bar1.

1

Indexierung table1.bar1 kann den> = NOW-Vergleich verbessern. Ein zusammengesetzter Index auf table2.foo_0 und table2.foo_20 wird helfen. Ein Index auf table2.foo_1 kann die Sortierung erleichtern.

Insgesamt kann das Einfügen der Ausgabe Ihrer Abfrage mit vorangestelltem EXPLAIN auch einige Hinweise geben.

0

Ein Index auf table1.foo_0, table1.bar1 könnte auch helfen, unter der Annahme, dass foo_20 zu Tabelle1 gehört.

Siehe How to use MySQL indexes und Optimizing queries with explain.

Verwenden Sie zusammengesetzte Indizes, die Ihren WHERE-Gleichheiten entsprechen (im Allgemeinen ganz linke Spalte im Index), WHERE Vergleich zu absoluter Wert (Mitte) und ORDER BY-Klausel (rechts, in der gleichen Reihenfolge).

2

Erstellen Sie die folgenden Indizes:

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

und schreiben Sie abfragen, wie folgt aus:

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 

Der erste Index für ORDER BY verwendet wird, wird der zweite für JOIN verwendet werden.

Sie, obwohl, kann mehr profitieren von dem ersten Index wie folgt zu erstellen:

CREATE INDEX ix_table1_0_1 ON table1 (bar, foo_0) 

die restriktive Filterung auf bar gilt.

Ich habe eine Blog-Post auf diesem:

, die auf Ratschläge, wie zu wählen, welcher Index für die Fälle, wie das zu schaffen.