Seite 1 von 1

MySQL Query-Cache vs. NOW() und CURDATE()

Verfasst: 29.01.2010, 19:42
von Synonym
Hallo zusammen,

ich stehe hier gerade vor einem Problem (seltsamen Zustand) den ich mir nicht erklären kann.

In einer Query wird das aktuelle Datum berücksichtigt und anhand dessen die Datensätze ausgewählt.

So, anfangs hatte ich dazu immer NOW(), doch Minuten und Sekunden brauche ich gar nicht. Also verwende ich aktuell CURDATE() um die Daten zu vergleichen.

Dachte eigentlich auch, dass diese Queries so cachebar wären, aber dem ist wohl nicht so.

Die komplette Query braucht mit NOW() oder CURDATE 0.3 Sek. Selbige Query in der Folge dauert genauso lange und kommt in dem Fall nicht aus dem QCache. Dachte ich aber, da die Query sich ja nicht ändert.

Nehme ich aber anstelle von NOW oder CURDATE einen festen Wert wie '2010-01-28', dann dauert die Query immer noch 0.3 Sek, aber nur beim ersten Aufruf. Alle weiteren kommen aus dem Cache.

So, gibt es dafür eine Erklärung?

Ich dachte bisher wirklich, dass Queries mit mysql-Funktionen als "statisch" betrachtet werden, eben nicht wie eine mit PHP time() die sich bei jedem Aufruf ändert.

Nachtrag: Hm, da hätte ich wohl vorher mal in die Doku sehen sollen. Bei Verwendung einer MySQL-Funktion wird der Cache nicht benutzt. Das ist ja unfug. Also doch per PHP vorher das ganze erledigen und dann Abfragen.

Verfasst:
von
SEO Consulting bei ABAKUS Internet Marketing
Erfahrung seit 2002
  • persönliche Betreuung
  • individuelle Beratung
  • kompetente Umsetzung

Jetzt anfragen: 0511 / 300325-0.


Verfasst: 30.01.2010, 12:07
von everflux
Genau, da hast du die Loesung auch direkt mit geschrieben.
Alternativ kannst Du das Ergebnis der Abfrage selber in php noch cachen und Dir so die gesamte Abfrage sparen, wenn die lediglich vom aktuellen Datum abhaengt. Dann hast Du nur einen cache-miss pro Tag :)

Verfasst: 30.01.2010, 12:19
von Synonym
Ja ne, das Ergebnis direkt cachen kann ich nicht, das kann sich nämlich schon öfters ändern, aber die eigentliche Query nicht. Die ändert sich eigentlich nie und sollte nur einen Vergleich machen zwischen dem aktuellen Tag und einem Zeitraum aus der Datenbank (Ferientermine). Mit PHP ist das ja kein Thema, aber verwundert hat mich das schon. Zumal man ja immer sagt "Was die Datenbank erledigen kann, das sollte sie auch erledigen". Und dann gibt es zig Daten-Funktionen und die verhindern das Cachen. Ist aus meiner Sicht echt unfug. Komischerweise aber ein from_unixtimestamp('mit Wert') nicht. Hm, egal, dann baue ich es halt wieder zurück wie es mal vor vielen Monaten war ;-)

Verfasst: 30.01.2010, 12:44
von profo
Synonym hat geschrieben:Komischerweise aber ein from_unixtimestamp('mit Wert') nicht.
Das ist doch eigentlich auch alles richtig. Das "now()" ändert sich ja bei jedem Aufruf, die Query kann mysql deshalb natürlich nicht cachen. Das "from_unixtimestamp(fester Wert)" wertet mysql eben als festen, unveränderlichen Wert aus, und kann die Query deshalb auch cachen.

Es kommt beim Cachen doch nicht darauf an, dass die Query gleich aussieht, sondern dass sie die identische Abfrage mit identischen Ergebnissen gibt... Ein "select rand()" sieht ja auch immer gleich aus, aber Du würdest an die Decke gehen, wenn MySQL das cachen würde :)

Verfasst: 30.01.2010, 14:19
von Synonym
@profo

Ja, das ist schon richtig. Da hatte ich falsch gedacht. Ich hing direkt an der Query fest, ob die nun immer gleich ist oder nicht.

und ein CURDATE() war für mich "gleich", ein PHP time() nicht.
Es kommt beim Cachen doch nicht darauf an, dass die Query gleich aussieht, sondern dass sie die identische Abfrage mit identischen Ergebnissen gibt
Richtig, aber dennoch ist es dann seltsam oder nur schwer verständlich. Denn auch ein CURDATE() liefert binnen eines Tages den gleichen Wert. Bei NOW() könnte ich es noch verstehen, wenn man davon ausgeht, dass die Funktion zuerst aufgelöst wird, denn dann ist es nichts anderes wie ein time(), aber bei CURDATE() nicht.

Verfasst: 30.01.2010, 14:38
von profo
Synonym hat geschrieben:Richtig, aber dennoch ist es dann seltsam oder nur schwer verständlich. Denn auch ein CURDATE() liefert binnen eines Tages den gleichen Wert.
Bei einem Funktionsaufruf mit nichtvorhersagbarem Ergebnis in der Query (curdate(), time(), subselect, usw.) sagst Du der Datenbank eigentlich explizit: bitte nicht cachen.

Mit einem "erst Query zusammenbauen, dann die zusammengebaute Query im Cache nachschlagen" würden sich die Datenbankler eine Reihe von Problemen aufhalsen, nur um ein Problem zu lösen, das vom falschem Gebrauch herstammt. Goldene Regel: eine Query selbst zusammenbauen und so einfach wie möglich halten.

Verfasst: 30.01.2010, 14:56
von Synonym
Ja klar, so mache ich das nun ja auch wieder. Hatte ich ja auch schon zuvor so. Da das aber bei allen Daten-Funktionen so ist frage ich mich da aber dann schon wozu man die dann eigentlich effektiv nutzen sollte / könnte. Wenn ich das eh mit PHP vorher machen muss, dann kann ich auch gleich einen Unix-Timestamp in die DB schreiben, das ist einfacher und geht schneller als ein DATE oder DATETIME oder TIMESTAMP von MySQL und dieses "umformen" in YYYY-MM-DD kann man sich dann auch sparen. Daher auch meine Gedanken.... Hatte das daher vorher auch nicht getestet. Ich dachte einfach die MySQL-eigenen Funktionen würden effektiver mit der DB zusammenarbeiten.

Verfasst: 30.01.2010, 15:06
von profo
Der Gedanke liegt ein bisschen nahe, weil die Datenbanken heute so verflixt viel können. Letzten Endes sind sie am effizientesten aber immer noch zu gebrauchen, wenn Du sie so weit es nur geht in Ruhe und so wenig und selten wie möglich arbeiten lässt :)

Übrigens, das Umwandeln in einen menschenlesbaren Zeitstempel war tatsächlich eher unnütz. Als Zeitfeld benutzen die meisten einfach einen besser performenden int(11) oder so, den Du mit time() bzw. in MySQL mit unix_timestamp() füllen kannst...

Verfasst: 30.01.2010, 15:23
von Synonym
Arg.... "Als Zeitfeld benutzen die meisten einfach einen besser performenden int(11) oder so, den Du mit time() bzw. in MySQL mit unix_timestamp() füllen kannst"
So hatte ich das ja zuvor :evil: Und dann der Umstieg auf die MySQL-Date-Funktionen. Wobei.... unix_timestamp() ganz sicher nicht.... Nene, ich bleibe dann wieder beim schönen alten time() :D

Verfasst: 30.01.2010, 15:28
von profo
Früher war alles besser 8)

Verfasst: 30.01.2010, 19:51
von 800XE
Synonym hat geschrieben:Da das aber bei allen Daten-Funktionen so ist frage ich mich da aber dann schon wozu man die dann eigentlich effektiv nutzen sollte / könnte.
na, in Abfragen wo nicht geCacht wird
(stell dir mal vor Airbag oder ABS hätten ein Caching .... bei Toyota wurde das glaub gerade bei den Gasspedalen eingebaut :lol: )

Was war zuerst da
Diese DatenFunktionen oder das Caching?

oder nach deiner Frage
(die Frage stelle ich hirmit wirklich ernsthaft)
was wurde "erfunden" was nicht hätte erfunden werden sollen(brauchen)
- Das Caching
- Die Datenfunktionen

abschweiff ....
... bei CPUs sind ja da auch voll die Auswüchse
erst gabs die Chaches in der CPU, Speicheraches
Dann gabs die Pipelines, das mehrere Befehle gleichzeitig durch die CPU laufen
dann wurden die Pipelines mehrspurig weil ja nach einem IF oderSo die "aktuelle" Spur in den Graben fährt ....

Verfasst: 30.01.2010, 19:54
von 800XE
Synonym hat geschrieben:Wobei.... unix_timestamp() ganz sicher nicht.... Nene, ich bleibe dann wieder beim schönen alten time() :D
ich arbeite auch mit dem time()


aber, Achtung

Y2K .... der kommt ... 2026 oder 2027 kommt der dort, wenn die den nicht von 32(bzw31) Bit auf 64 oder so "aufbohren"
(oder ist der jetzt nur bei 16 bzw 15 Bit?)

www.800xe.de/hphilo/Y2K-Bug-2027.html
Im Februar 2027 war es dann soweit und der Integer ist übergelaufen.