2009-08-19 4 views
4

Ich versuche, relativ große Mysql (Myisam) -Tabelle mit 220.000 Zeilen zu optimieren. Die Tabelle selbst ist nicht so groß - etwa 23,5 MB groß. Also, was ist das eigentliche Problem? - Ich habe Abfrage wie folgt:Wie optimiere ich mysql date_format() für Geschwindigkeit in Where-Klausel?

SELECT * FROM table WHERE DATE_FORMAT(date_field, '%m%d') = '1128' LIMIT 10 

Ich habe versucht, einen Index für DATE_FIELD zu setzen, sondern zeigen erklären, dass der Index nicht verwendet wurde ... Ich denke, dies ist wegen der DATE_FORMAT nicht so fremd ist(). Also plane ich, eine weitere Spalte hinzuzufügen, die die Daten als '% m% d' enthält, und einen Index darauf zu setzen. Der einzige Grund, warum ich dies nicht tun möchte, ist die Datenduplizierung.
Btw ich DATE_FIELD verwenden ist ein birth Feld und ich bin sicher, ich brauche immer die DATE_FIELD als% Y-% m-% d oder d m%%

Haben Sie besseren Vorschlag haben, wie die Abfrage zu optimieren über ? Danke im Voraus !!!

Einige Informationen:

MySQL Version: 5.0.51b-log
OS: Slackware 12.1
CPU: Pentium III (Coppermine) bei 996.783Mhz
RAM: 512 MB DDR
HDD: 80 GB SATA

PS ich versuchte, eine weitere Spalte hinzuzufügen, die die Daten als% m% d halten. Die Ergebnisse sind sehr gut, aber ich mag diesen Ansatz immer noch nicht. Ich warte auf weitere Vorschläge!

Antwort

2

Wenn Sie immer einen Platzhalter auf das Jahr benötigen, wie Ihre Frage, ich bin nicht sicher, dass MySQL in der Lage sein wird, einen Index auf ein Datum/Datetime-Feld zu verwenden

Wenn diese nur Termine sind, können Sie Erstellen Sie jedoch eine time_dimension-Tabelle und füllen Sie diese für die nächsten Jahre mit einem Kalender auf. Ich habe eine gespeicherte Prozedur, um das zu tun, wenn Sie eine brauchen sollten.

create table time_dimension (
dbdate date primary key, 
year int NOT NULL, 
month int NOT NULL , 
day int NOT NULL, 
KEY(year), 
KEY(month); 
KEY(day); 
); 

Sie würden Ihre große Datentabelle zu dieser relativ kleinen Tabelle hinzufügen und auf ihr Feld filtern. z.B.

SELECT * FROM data_table d 
    inner join time_dimension t 
    on d.date_field=t.dbdate 
where t.day=28 and t.month=11 LIMIT 10 

Diese nutzt Filterung auf dem kleinen time_dimension und schließt sich auf DATE_FIELD = DbDate normalerweise Indizes verwenden.

+0

Vielen Dank für die Anregung nos! Ich denke nicht, dass es in meinem Fall sehr nützlich ist (ich habe ein paar Notizen eingefügt), aber im Allgemeinen ist das eine gute Richtung !!! – plamen

+0

Es ist auch gut für die Zukunft. Wenn Sie alle Donnerstage filtern möchten, fügen Sie einfach eine weitere Spalte zu time_dimension hinzu und verwenden Sie t.dayname = 'Thursday'. Oder alle Wochenenden in einem Monat werden, wo t.year = 2009 und t.month = 9 und t.weekend_flag = 1 :-) – nos

+0

, die nicht wirklich hilft nicht, wenn sie mit Geburtsdatum zu tun, wenn die Datenbank in Richtung Kleinkinder ausgerichtet ist. – jmucchiello