Dies sollte Ihnen helfen. Schreiben Sie Ihre Abfrage wie folgt um:
SELECT c1, Sum(c2)
FROM table
WHERE c4 = 2011
AND c5 = 0
AND c6 In (6,9,11)
AND c3 IS NOT NULL
GROUP BY c1
Erstellen Sie nun einen zusammengesetzten Index für Spalten (c4, c5, c6) mit den Spalten IN DIESER REIHENFOLGE. Die Spalten in Ihrem Index sollten in derselben Reihenfolge erscheinen wie die Spalten in Ihrer WHERE-Klausel. Andernfalls funktioniert der Index nicht. Die Selektivität dieses Index ist eng genug, dass eine Dateisortierung in der temporären Tabelle (für die Gruppierung nach) schnell sein sollte.
Der Grund, c3 an das Ende der Abfrage zu verschieben, ist der folgende. Nehmen wir als Beispiel an, dass c3 Werte zwischen 0 und 100 annehmen kann (oder NULL sein kann). Wenn Sie eine „IS NOT NULL“-Abfrage ausführen, muss MySQL fast den gesamten B-Tree-Index durchlaufen, mit Ausnahme der Kanten, die NULL entsprechen. Daher entscheidet MySQL, dass ein vollständiger Tabellenscan eine einfachere Option ist, als alle verschiedenen Pfade im Index zu durchlaufen. Andererseits werden Sie sehen, dass Mysql diesen Index verwenden wird, wenn Ihre Abfrage "IS NULL" und Ihr Index (c3, c4, c5, c6) war. Dies liegt daran, dass MySQL in diesem Fall nur den Teil des Indexbaums durchlaufen muss, der dem NULL-Wert entspricht.
Die Art der Indizes, die MySQL benötigt, hängt stark von der jeweiligen Abfrage ab. Das Erstellen von Indizes für alle Spalten, wie @louis vorgeschlagen hat, ist KEINE gute Idee!