8

Ich habe große Tabelle mit 22 Millionen Datensätze. Ich möchte nächste Abfrage auszuführen:MySQL Abfrage nach Datum mit großen inverval

select auto_alerts from alerts_stat where endDate > "2012-12-01" 

Leistung zu verbessern Ich habe BTREE Index für ENDDATA Feld:

CREATE INDEX endDate_index USING BTREE ON alerts_stat(endDate) 

Nachdem ich starten Abfrageausführungsplan analysieren:

Wenn ich will Parameter von 15 bis 7 Tagen vorher abrufen:

explain select alerts_sp from alerts_stat 
where endDate between CURDATE() - 15 and CURDATE() - 7; 

Ich habe den nächsten Ausführungsplan, um 2.762.088 Zeilen zu bearbeiten.

'1', 'SIMPLE', 'browser_plugin_alerts_stat', 'range', 'endDate_index', 'endDate_index', '4', NULL, '2762088', 'Using where' 

Wenn ich um einen Tag Intervall zu erhöhen, die ich erhielt:

explain select alerts_sp from alerts_stat 
where endDate between CURDATE() - 15 and CURDATE() - 6; 

sagte EXPLAIN MySQL Plan alle 22.923.126 Zeilen zu verarbeiten.

'1', 'SIMPLE', 'browser_plugin_alerts_stat', 'ALL', 'endDate_index', NULL, NULL, NULL, '22932390', 'Using where' 

Zum Beispiel wählen Sie ohne Bedingungen in WHERE Prozess 22.925.642.

Darf ich den Ausführungsplan verbessern? Vielleicht habe ich irgendwo einen Fehler oder ist normales MySQL-Verhalten?

Antwort

3

Wenn der Resultset 8-9% aller Zeilen überschreitet, führt MySQL einen vollständigen Tabellenscan durch. Für mich sieht es so aus, als würde man eines Tages MySQL in voller Tabellen-Scanrichtung hinzufügen. Sie könnten versuchen, Index zu erzwingen, um zu sehen, ob das Ergebnis besser ist.

UPDATE:

Von dem, was ich gelesen habe, MySQL Query Optimizer neigt dazu, in Grenzfällen wie dies falsch zu wählen, so könnte es besser einfach zu arbeiten, einen Index zu erzwingen. Ansonsten ist dies eine einfache Abfrage, und ich habe nicht viel mehr Platz für die Optimierung.

Vielleicht könnte die Erstellung eines Covering index auf diesen beiden Spalten und die Erzwingung seiner Verwendung die besten Ergebnisse liefern.

+0

Danke. Denke, es ist mein Fall. Es ist also MySQL-spezifisches Verhalten. Kann ich die Abfrage irgendwie verbessern, um beispielsweise sum ('alerts_sp') ​​für große Intervalle zu erhalten? – Taky