it-swarm.com.de

Lohnt es sich, den Wert vor dem Aktualisieren mit select zu überprüfen?

Ich habe einen booleschen Wert tinyint in meiner Zeile, der standardmäßig 0 Und 1 Ist, wenn eine bestimmte Sache passiert. Nachdem es 1 Ist, bleibt es immer 1. Jetzt kann diese bestimmte Sache für jede Zeile viele Male passieren, aber ich muss den Wert nur einmal auf 1 Aktualisieren.

Lohnt es sich, ein SELECT zu machen, den Wert zu überprüfen und nur dann, wenn der Wert 0 Ist, das UPDATE auszulösen?

Würde vielleicht auch das

UPDATE table SET lock='1' WHERE id='100' AND lock='0'

besser sein als

UPDATE table SET lock='1' WHERE id='100'

für meine Situation?

6
McCuz

Ja, es lohnt sich aus mehreren Gründen:

  • Sie können von Indizes für diese Spalte profitieren.
  • Es scheint ein sinnloses Update für Fälle zu sein, in denen es bereits 1, aber möglicherweise wird ein Trigger für die Aktualisierungstabelle ausgeführt.
  • Vermeiden Sie es, zusätzliche Zeilen aus dem Aktualisierungsvorgang zu protokollieren. Selbst wenn der vorherige Wert mit dem neuen übereinstimmt, protokolliert die Datenbank den Vorgang dennoch (anders würde der Wert derselben Spalte lock zugewiesen, die in diesem Fall übersprungen würde).
4
EzLo

Nun, "13.2.11 UPDATE Syntax" schlägt vor, dass kein Schreiben durchgeführt wird, wenn sich der Wert nicht wirklich ändert.

Wenn Sie eine Spalte auf den aktuellen Wert setzen, bemerkt MySQL dies und aktualisiert sie nicht.

Die erweiterte WHERE -Klausel wird daher nicht benötigt, um unnötige Schreibvorgänge zu vermeiden.

Die erweiterte WHERE -Klausel bietet jedoch möglicherweise einen winzigen Leistungsvorteil, da kein zu aktualisierender Datensatz gefunden wurde. Die zu überprüfende Logik, ob die Zeile tatsächlich geändert werden muss, wird nicht ausgeführt. Aber das ist wirklich winzig.

Und der Aufwand für das Abrufen ist in beiden Fällen vorhanden. Sie können nur versuchen, es mit Indizes zu unterstützen (auf id und lock (zusammengesetzt) ​​für die erweiterte Version und auf id für die andere).

5
sticky bit

EzLo hat Sie mit einer guten Liste von Positiven bedeckt, und ich werde nur ein Negativ herauswerfen. Ich glaube nicht, dass dies auf IHREN Fall zutrifft, aber ich nehme dies hier für andere Leute auf, die diese Antwort möglicherweise später für ihre eigenen Zwecke lesen.

Wenn Ihre Abfrage möglicherweise mehrere Felder aktualisiert, ist die Erstellung all dieser verschiedenen Abfragen mit Kosten verbunden:

Angenommen, wir aktualisieren nur den Nachnamen einer Person:

UPDATE dbo.Users 
  SET LastName = 'Smith' 
  WHERE id='100' AND LastName = 'Jones';

Angenommen, wir aktualisieren auch den Nachnamen und die Adresse:

UPDATE dbo.Users 
  SET LastName = 'Smith',
      StreetAddress = '123 Main Street',
      City = 'San Francisco',
      State = 'CA'
  WHERE id='100' 
    AND LastName = 'Jones'
    AND City = 'New York'
    AND State = 'NY';

Um eine solche Abfrage zu erstellen, müssen Sie in Ihrem App-Code viele Gleichheitsprüfungen durchführen. Um die Sache noch schlimmer zu machen, werden Sie den Plan-Cache mit vielen verschiedenen Aktualisierungszeichenfolgen aufblähen, die ausgeführt werden, wenn verschiedene Kombinationen von Parametern verwendet werden - manchmal aktualisieren wir nur Nachname, manchmal aktualisieren wir Nachname und Stadt, manchmal Wir aktualisieren Stadt und Bundesland, aber nicht Nachname usw.

5
Brent Ozar

Vorausgesetzt

  • Keine TRIGGER
  • Keine Replikation
  • id ist das PRIMARY KEY des Tisches; Das heißt, nur eine Zeile entspricht id=100 und id ist indiziert.

Dann

  • Tun Sie nicht das SELECT - es tut etwas, was das UPDATE tun wird.
  • Mach nicht den SELECT - KISS.
  • AND lock='0' ist optional, da id=100 reicht aus, um die Filterung auf eine einzelne Zeile zu beschränken. (Wenn Sie erwartet hätten, dass mehrere Zeilen übereinstimmen, wäre das ANDwahrscheinlich vorteilhaft, und es könnte von einem Indexstart profitieren wird lock.)

Denk darüber so:

  • Alle vorgeschlagenen Formulierungen erfordern das Betrachten einer Reihe.
  • Das Abrufen einer Zeile zum Anschauen ist mäßig kostspielig.
  • Zwei Abfragen sind teurer als eine.
  • Ihre Programmierzeit ist noch teurer, also KISS.

Eine Randnotiz (zu einem der Kommentare):

  • id = '100' wird zu id = 100 während des Parsens; also kein signifikanter Leistungsunterschied. In beiden Fällen wird der Index (z. B. PK) für id verwendet.
  • varchar_col = 100 ist schlecht; Jede Zeile muss überprüft werden, um festzustellen, ob varchar_col konvertiert in die Zahl 100. Kein Index für varchar_col ist nicht nützlich.
2
Rick James

Es lohnt sich nicht, vorher ein SELECT durchzuführen, und dies kann sogar die Leistung Ihres Systems beeinträchtigen. Ihr RDBMS muss diese SELECT-Funktion (Durchsuchen der zu aktualisierenden Zeile) ohnehin beim UPDATE ausführen. Das UPDATE selbst ist (im Vergleich zur Suche) vernachlässigbar schnell. Kosten und Overhead (Netzwerklatenz + Ihre Überprüfung, ob aktualisiert werden soll oder nicht) sind für zwei Vorgänge (SELECT + UPDATE) viel, viel höher als nur UPDATE allein aufzurufen.

Es wurde angegeben, dass Sie von Indizes profitieren würden. Dies ist nicht der Fall, da der Index beim ersten (und einzigen) Setzen von 0 auf 1 bereits neu erstellt wurde.

2
Felix Roske