[MySQL] optimierung

ActionScripter

Scripter auf Abruf
ID: 141403
L
17 Oktober 2006
484
39
hallo zusammen,

ich benutze für diverse configurations-einstellungen und counter etc. (key, value) eine tabelle, die nur diese zwei spalten hat. ein normaler update-befehl zum speichern/ändern eines eintrages geht demnach:

PHP:
UPDATE config SET val='blabla' WHERE var='blubber'
primärindex ist natürlich sinnigerweise auf var gelegt. nun zu meiner frage ... eine andere möglichkeit, die werte zu speichern wäre ja z.b.

PHP:
REPLACE INTO config (var,val) VALUES ('blabla','blubber')
wie ist das rein mysql-technisch gelöst? wird da auch erst nach dem index gesucht oder wird der eiskalt ohne bedenken überschrieben ... soll heissen: ist das replace schneller und weniger "belastend" als ein update? wenn ja, dann würde ja der zweite query der sinnvollere sein. kennt sich da vielleicht jemand genau aus??
 
https://www.mysql.org/doc/refman/5.1/de/replace.html

REPLACE funktioniert auf exakt gleiche Weise wie INSERT. Der Unterschied besteht darin, dass, wenn ein alter Datensatz denselben Wert wie ein neuer Datensatz für einen Primärschlüssel oder einen eindeutigen Index hat, der alte Datensatz gelöscht wird, bevor der neue eingefügt wird. Siehe auch Abschnitt 13.2.4, „INSERT“.

REPLACE ist eine MySQL-Erweiterung zum SQL-Standard. Es kann Datensätze einfügen, oder es kann Datensätze löschen und einfügen. Wenn Sie eine Anweisung suchen, die dem SQL-Standard entspricht und die entweder einfügt oder aktualisiert, dann benutzen Sie die INSERT ... ON DUPLICATE KEY UPDATE-Anweisung (siehe auch Abschnitt 13.2.4.3, „INSERT ... ON DUPLICATE KEY UPDATE“).
Rein aus dem Bauch heraus hätte ich jetzt auch zu ON DUPLICATE KEY UPDATE gegriffen, allerdings wusste ich auch nicht mehr das bei REPlACE der Primärschlüssel mit dem selben wert erst gelöscht wird, bevor der neue Wert eingefügt wird. Ich hatte es damals mal gelsen aber irgendwie verdrängt :roll:.

Wenn sicher ist das der Wert in der Tabelle sowieso existieren muss würde ich deine erste Query nehmen, wenn es auch sein kann das es den Wert noch nicht gibt würde ich ON DUPLIKATE... nehmen.

*edit
BTW:
MySQL verwendet für REPLACE (und LOAD DATA ... REPLACE) den folgenden Algorithmus:
  1. Es wird versucht, den neuen Datensatz in die Tabelle einzufügen.
  2. Wenn die Einfügeoperation aufgrund einer Schlüsseldublette in einem Primärschlüssel oder einem eindeutigen Index fehlschlägt,
    1. wird der konfliktauslösende Datensatz mit dem doppelten Schlüsselwert aus der Tabelle entfernt,
    2. wird erneut versucht, den neuen Datensatz in die Tabelle einzufügen.
Das kommt mir auch so vor, als ob man da den Ochsen am Schwanz pakt, also für mich bissi unlogisch, oder kann mich da einer aufklären!?
 
Zuletzt bearbeitet:
... ON DUPLICATE KEY ...
ich fürchte, wir haben da ein bisschen aneinander vorbei gelesen. es geht mir nicht darum, neue wertepaare zu erzeugen. ich möchte lediglich bestehende werte updaten und das möglichst datenbankschonend.

hat also nichts mit INSERT zu tun :)

dein zweites zitat scheint mir aber schon recht aussagefähig dazu zu sein. offenbar versucht replace erst ein INSERT und im fehlerfall wird ein DELETE und nochmal ein INSERT angewendet. ist also wahrscheinlich datenbanklastiger, als ein UPDATE, was nach meinem verständnis die gleichen schlüssel-checkroutinen durchläuft wie ein INSERT, aber im gegensatz zu REPLACE nur dann etwas einfügt bzw. ändert, wenn eine indexübereinstimmung gefunden wurde. da ich das REPLACE immer als update (miss-)brauchen will in diesem fall, wird wohl immer die komplette INSERT > ERROR > DELETE > INSERT -prozedur benötigt werden ....

oder hat da noch jemand andere infos dazu??

[edit]das einzig gute ist, dass ich mit REPLACE mehrere zeilen in einer abfrage ändern kann, was mit einem UPDATE nicht geht[/edit]
 
Ehm naja vorbei greredt nicht ganz. Ich sagte ja "wenn du sicher bist das der wert auf jedenfall da ist" nimm update, " wenn es auch sein kann das der wert noch nicht da ist" nimm ON DUPLIKAT KEY, weil wenn mysql den insert machen will und merkt aha da ist schon dieser key ändert sich die Query in eine update Query.

Btw. Wieso soll man mit Update nicht auch mehrere Datensätze updaten können. Das geht doch genauso wie bei REPLACE oder nicht? *gestehe kenne die replace syntax nicht so*
 
:-? mal ne dumme frage, wie oft willst du bitte deine settings aktualisieren?

und klar ist update schneller als nen replace... nen update sucht einfach im index nach den datensatz und ändert dann den datensatz. wohin gegen ein replace auch erstmal schauen muss ob es den index gibt, wenn ja wird der index + der datensatz gelöscht, und danach wird ein neuer datensatz angelegt. wobei anlegen wiederrum heißt das auch der index geupdatet werden muss und das kann unter umständen recht "lange" dauern. (dazu mal 2 wörter in den raumgestellt btree, umverteilung)
 
naja das kommt auf die änderung an.

du kannst ja sehr wohl mehrere datensätze ansprechen wenn du z.B. WHERE var = 'blablub' AND var = 'blubbla' machst.

wie strolch00 schon gesagt hat, wenn die datensätze sicher da sind dann nimm UPDATE, ansonsten ist wohl ON DUPLICATE KEY das richtige, weil das dann entweder einfügt oder ein update macht.

ON REPLACE ist wenn ich dich richtig verstanden habe, für dich unsinnig weil ja im fehlerfall der entsprechende datensatz gelöscht wird und nicht upgedatet. und das vergeudet ja wieder ressourcen. weil gelöscht und wieder eingefügt werden muss.

jperl
 
naja das kommt auf die änderung an.
du kannst ja sehr wohl mehrere datensätze ansprechen wenn du z.B. WHERE var = 'blablub' AND var = 'blubbla' machst.

??? zeilenweise ... das heisst:
PHP:
UPDATE table SET val='123' WHERE var='var1';
UPDATE table SET val='321' WHERE var='var2';
wie will ich das denn in einem aufruf machen?
 
Achso verschiedene Werte in dem Update ok dann leuchtet das ein, aber nur aus neugier kann das Replace? Lt. Manual dachte ich damit kann man auch nur einen Wert einfügen und wenn der Index halt öfter vorkommt(aus älteren versionen) werden alle gelöscht und einer eingefügt. Also so habe ich das verstanden mit dem Replace, ich kann mich aber wie so oft irren :yawn:.
 
Achso verschiedene Werte in dem Update ok dann leuchtet das ein, aber nur aus neugier kann das Replace? Lt. Manual dachte ich damit kann man auch nur einen Wert einfügen und wenn der Index halt öfter vorkommt(aus älteren versionen) werden alle gelöscht und einer eingefügt. Also so habe ich das verstanden mit dem Replace, ich kann mich aber wie so oft irren :yawn:.

ja... replace hat den selben sytax wie insert. somit kannste das ganze wie ein erweitertes insert machen. so in art von
PHP:
REPLACE table (feld1,feld2) VALUES (1,2),(3,4),(5,6) usw...
aber replace hat nen entscheidenten nachteil du kannst nicht mehr rechnen... zb bei nem counter kannste nicht mehr feld=feld+1 machen.

diverse counter, caches und jackpots eigentlich ständig, wieso?
achso hatte vorns was von einstellungen gelesen... und eigentlich werden die nicht täglich geändert. aber update ist da schon die performanteste lösung... heißt nicht umsonst update.

ps: der server hält auch mehr als ein update aus ;)
 
so, da muss ich mich nun auch einaml reinzwängen und bringe ein gutes argument mit, replace nicht zu nutzen:
erstmal müssen wir uns klar werden, was bei einem replace passiert, ein datensatz wird gelöscht und die schlüssel von diesem datensatz, die ja sortiert vorlegen, werden entfernt. nun geht mysql dann hin, fügt einen neuen datensatz einen und muss erstmal mit der binären Suche feststellen wo genau der schlüssel hingeschrieben wird, tut dies und fügt einen neuen datensatz in die datendatei ein. nun haben wir 2 mal die datei mit den schlüssel geändert ohne, dass es sinn gemacht hat, und dies ist nicht wirklich die schnellste operation.
würden wir nun einfach ein update-query nutzen, welcher NICHT eine spalte ändert, die ein schlüssel ist, könnte er die schlüsseldatei komplett in ruhe lasse und würde zu dem datensatz in der datendatei springen und diesen ändern, ist das tabellenformat nun starr und nicht dynamisch geht dies nochmal um ein ganzes schneller.
es ist wichtig zu wissen (wenigstens im ansatz) was in der datenbank vorgeht um solche optimierungen durchzuführen, ich würde mir auch überlegen, ob du nicht weit mehr geschwindigkeit rausholst, wenn du das datenbank-schema änderst oder querys änderst, die weit öfter ausgeführt werden, denn datensatz-verändernde querys brauchen immer eine gewisse zeit, mit select querys, die ja bekanntlich (quasi-)paralllel ablaufen ließe sich an anderen stellen also weit mehr geschwindigkeit rausholen.
ja, ich gebe zu ich bin datenbankgeschädigt, aber optimierungen an datenbanken sind genial^^
 
jo, also sind wir uns jetzt anscheinend alle einig, dass replace nicht optimal ist. schade, wäre ja auch zu schön gewesen :)

ja, ich gebe zu ich bin datenbankgeschädigt, aber optimierungen an datenbanken sind genial^^
ja ja ... ich weiss noch, wie ich sowas früher mit autoexec.bat und config.sys versucht habe ... muss doch immer noch das eine oder andere byte rauszuquetschen sein :)