Ankündigung

Einklappen
Keine Ankündigung bisher.

AI - Spalte ändert sich bei UPDATE

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • #16
    ja... Hier habe ich den Zeichensatz bei der Exportfunktion nicht korrekt gewählt.

    Kommentar


    • #17
      Zitat von olruebe Beitrag anzeigen
      @chorn: Ich habe keine 441 Datensätze! Es bleiben 15 Stück. Nur die ID steigt auf 441 an, wobei 441 nur ein Beispiel ist. Je länger ich warte, desto höher steigt die ID.
      Die IDs der bestehenden Datensätze ändern sich oder nur der Auto Increment Wert der Tabelle?! (Der Auto Increment Wert ist der Wert, der einem neu eingfügeten Datensatz gegeben wird.)

      Kommentar


      • #18
        Zitat von chorn Beitrag anzeigen
        Perry Staltic die Anzahl und Zusammensetzung der Keys hat er doch schon längst revidiert:

        Erschliesst sich mir nicht, warum er einen davon ignorieren sollte.
        Wovon ignoriert wer was?
        Ja er hat 2 (unique) Keys, hab ich was anderes geschrieben?

        Ich spreche davon, dass sein Konstrukt laut Doku genau das macht, was dokumentiert ist.
        Gemäß Doku verhält sich mysql so, wie der TE es beschreibt. Die AI werden hochgezählt, obwohl "nur ein Update " durchgeführt wird.
        Es ist also aus mysql Perspektive alles so, wie es sein soll. Leider ist es nicht das, was der TE möchte.
        Deswegen habe ich ihm empfohlen, sein Datenmodell zu ändern und seinen Insertprozess anzupassen.

        Vielleicht muss nicht beides sein, mir erschließt sich aber nicht, warum er 2 eindeutige Keys braucht. Daher kann ich da keine Empfehlung abgeben. Durch die Aussage, dass er Innodb einsetzt, ist immerhin klar, dass alles nach Vorgabe läuft.
        Probehalber kann olruebe ja die Engine tauschen, dann sollte es ja so laufen wie er es will. Aber damit handelt er sich vielleicht andere Dinge ein, die nicht empfehlenswert sind.

        Engine, Datenmodell, Insertprozess, eins davon muss minimal angefasst werden.

        Kommentar


        • #19
          @erc: Die ID ändert sich. Wenn ich die Tabelle leere und dann meine Scanner starte, bekomme ich zunächst 15 Datensätze mit den IDs 1-15. Nach 3 Minuten habe ich dann immernoch 15 Datensätze, jedoch mit IDs zwischen 1 und 441.

          @ Perry Staltic: Ich sehe das anders. Es macht eben gerade NICHT, was die Doku sagt.
          The effects are not identical for an InnoDB table where a is an auto-increment column. With an auto-increment column, an INSERT statement increases the auto-increment value but UPDATE does not.
          So wie ich die Doku verstehe, zählt der AI hoch, nachdem ein Insert durchgeführt wurde. Das macht ja auch sinn. Wird aber kein Insert durchgeführt, sondern ein UPDATE (auf Grund der Tatsache, dass es diesen Unique-Key schon gibt), sollte der AI unverändert bleiben.
          but UPDATE does not.
          Auch wenn mein Statement mit "INSERT" beginnt, wird ja durch den sonst doppelten Key ein UPDATE durchgeführt.

          Gegen Deine Theorie, dass alles so korrekt ist, spricht auch die Tatsache, dass die ID nicht bei jedem Update hochzählt. JEDER Datensatz wird bei mir sekündlich aktualisiert. Ich kann mir das auch ansehen. Der Timestamp und einige andere Werte ändern sich ständig, die ID aber nur ab und an. Manchmal läft es 3 Minuten sauber. Dann ändert sich die eine oder ander ID aber wieder. Wenn das Doku-Konform wäre, müsste es ja auch bei jedem Update so laufen...

          Wenn ich das in 2 Aufrufe zerlege (erst abfragen ob Datensatz existert und dann in zweitem Aufruf entweder INSERT oder UPDATE), würde ich, wenn ich richtig informiert bin, die MySQL-Last verdoppeln. Da ich etwa 100 BT-Geräte und 20-30 Scanner habe (wobei nicht jedes BT-Gerät in der Richweite aller Scanner ist) komme ich schnell auf etwa 600 - 700 Aufrufe pro Sekunde, die ich verdoppeln würde. Ich glaube bei dieser Zahl macht es schon sinn auf Performance zu achten, oder seht Ihr das anders?

          Es scheint aber so zu sein, dass ein reines UPDATE-Statement den "Fehler" nicht herbeiführt. Ich habe jetzt mal alle Datensätze eingetragen und nun das Statment auf ein UPDATE geändert und seit etwa 7 Minuten läuft es ohne dass die ID sich ändert.

          Wie wäre folgender Ansatz aus Perfomance-Sicht:
          Ich mache erst einen Update und frage dann die effected Rows ab. Wenn >0, beende ich das Skript. So hatte ich nur einen MySQL-Aufruf.
          Wenn 0, schiebe ich noch einen INSERT hinterher. So dürfte ich bei der jeder Scanner-BT-Kombination nur Einmalig einen doppelten Aufruf haben.

          Meiner Meinung nach, ist mein ursprünglicher Weg immernoch der Richtige. Dass das Verhalten Regelkonform ist, bezweifle ich. Der beschrieben Bug ist aber irgendwie auch was anderes. Wenn ich es richtig verstehe geht es in dem Bug darum, dass fälschlich der AI-Wert hochzählt und beim nächsten Insert dann zu hoch ist. Bei mir ist es ja aber so, dass sich die IDs bereits bestehender Datensätze ändern.

          Hmm...?!?


          Kommentar


          • #20
            Zitat von olruebe Beitrag anzeigen
            @erc: Die ID ändert sich. Wenn ich die Tabelle leere und dann meine Scanner starte, bekomme ich zunächst 15 Datensätze mit den IDs 1-15. Nach 3 Minuten habe ich dann immernoch 15 Datensätze, jedoch mit IDs zwischen 1 und 441.
            Das wäre dann ein ziemlich böser Bug in Mysql. Du kannst davon ausgehen, dass der Fehler in deinem Code liegt. Schau dir dein Code nochmal genau an, überall wo auf die Tabelle zugegriffen wird. Wenn das nicht hilft kannst du das Query Log von Mysql aktivieren. Da drin werden sämlich Abfragen protokolliert. Wenn damit auch nicht nachvollziehbar ist, warum sich die Ids ändern, hast du vielleicht ein Bug gefunden.

            Zitat von olruebe Beitrag anzeigen
            Wenn ich das in 2 Aufrufe zerlege (erst abfragen ob Datensatz existert und dann in zweitem Aufruf entweder INSERT oder UPDATE), würde ich, wenn ich richtig informiert bin, die MySQL-Last verdoppeln.
            Bei solchen sinnlos Queries kannst du problemlos eine 5 stellige Anzahl pro Sekunden durchfeuern. Nebenbei zwingt dich auch keiner zwei Queries auszuführen. Du kannst Updaten, schauen ob sich etwas geändert hat, wenn nein, ein Insert ausführen. Das wird wahrscheinlich unterm Strich schneller sein. Sowie ichs verstanden habe, tritt ein Insert nur im Promillebereich auf und der Hauptteil läuft auf ein Update hinaus.

            Kommentar


            • #21
              Ich bin mir jetzt sicher und habe auch mit nachlesen nur Infos bei msdn gefunden, aber wenn ich das richtig sehe, dann erstellt deine Tabelle erst eine ID als primary key und dann noch einen unique Index für ID. Das ist wohl dein Problem.
              Schmeiss den unique Index für id raus raus und lasse ihn nur als PK.

              Teile mit ob es das gewesen ist.

              Kommentar


              • #22
                @erc: Dieses...
                $sql =" INSERT INTO ma_location ( `scanner_id`, `beacon_major`, `beacon_minor`, `distance`, `TX`, `RSSI`, `timestamp`) VALUES ('".$ReveiverID."', '".$_POST["Major/Instance"]."', '".$_POST["Minor"]."', '".$dist."', '".$_POST["TX"]."','".$_POST["RSSI"]."', now())
                ON DUPLICATE KEY UPDATE `distance` = '"
                .$dist."', `TX` = '".$_POST["TX"]."', `RSSI` = '".$_POST["RSSI"]."';" ;
                ...ist im Moment der einzige SQL-Code der auf dieser Tabelle(!) ausgeführt wird. Mehr mache ich im Moment mit der Tabelle nicht. Ich trage ein und update die Werte. Mehr passiert im Moment nicht. Die Ergebnisse sehe ich mir im Moment lediglich in PHPmyadmin an. Hier habe ich den Fehler festgestellt.

                Erkennt Ihr in dem SQL einen Fehler, der mein Problem hervorrufen könnte?

                Und Dnke für den Hinweis "5-Stellig". Das beruhigt mich! Und ja: Insert sind nur sehr wenige, Update die Hauptaufgabe.

                @potestix: Ich habe den Unique von der ID entfernt. Die ID ist jetzt ein Primary-Key. Trotzdem tritt es noch auf.
                ALTER TABLE `ma_location`
                ADD PRIMARY KEY (`ID`),
                ADD UNIQUE KEY `One_Scanner_Beacon` (`scanner_id`,`beacon_major`,`beacon_minor`) USING BTREE;
                Das Logging werde ich morgen mal testen. Habe ich eben kurz getestet, hatte aber nach wenigen Sekunden 6.300 Zeilen in der Log-Tabelle.

                Kommentar


                • #23
                  Hier haut was nicht hin. Ein derartigen Bug halte ich für praktisch ausgeschlossen. Angenommen es stimmt, dass es nur diesen einen Query auf diese Tabelle gibt und es kein Bug ist. Dann muss das Falsch sein:

                  Die ID ändert sich. Wenn ich die Tabelle leere und dann meine Scanner starte, bekomme ich zunächst 15 Datensätze mit den IDs 1-15. Nach 3 Minuten habe ich dann immernoch 15 Datensätze, jedoch mit IDs zwischen 1 und 441.
                  Es gibt ein Szenario bei dem sich die Ids streuen können. Fakt ist, der Auto Increment Wert erhöht sich, mit jedem mal wenn der Query ausgeführt wird. Angenommen die Tabelle ist geleert und Gerät A liefert 3 Datensätze ein. Dann bekommt der erste Datensatz ID 1 und die nächsten zwei Datensätze führen zu einem Update. Der nächste Auto Increment Wert ist damit 4. Was passiert, wenn in dem moment Gerät B erstemalig ein Datensatz liefert? Es bekommt ID 4. Klar?! Der Teil mit "bekomme ich zunächst 15 Datensätze mit den IDs 1-15" ist nicht so. Das kannst du relativ einfach prüfen. Lass das einfach länger laufen. Nach dem alle Geräte einmal Daten geliefert haben, "ändert" sich keine ID mehr. Noch mal deutlich, die IDs ändern sich überhaupt nicht. Die Vergabe ist nur lückenhaft.

                  Kommentar


                  • #24
                    Zitat von olruebe Beitrag anzeigen
                    @erc: Die ID ändert sich. Wenn ich die Tabelle leere und dann meine Scanner starte, bekomme ich zunächst 15 Datensätze mit den IDs 1-15. Nach 3 Minuten habe ich dann immernoch 15 Datensätze, jedoch mit IDs zwischen 1 und 441.

                    @ Perry Staltic: Ich sehe das anders. Es macht eben gerade NICHT, was die Doku sagt.


                    So wie ich die Doku verstehe, zählt der AI hoch, nachdem ein Insert durchgeführt wurde. Das macht ja auch sinn. Wird aber kein Insert durchgeführt, sondern ein UPDATE (auf Grund der Tatsache, dass es diesen Unique-Key schon gibt), sollte der AI unverändert bleiben.
                    Auch wenn mein Statement mit "INSERT" beginnt, wird ja durch den sonst doppelten Key ein UPDATE durchgeführt.
                    ...
                    Hmm...?!?

                    Wo ist denn das Problem, einmal einen Test mit der anderen Engine zu machen?
                    Ich finde die Formulierung in der Doku auch nicht gelunden aber seis drum, hier ist das komplette Statement:
                    14.2.5.3 INSERT ... ON DUPLICATE KEY UPDATE Syntax

                    If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY, MySQL performs an UPDATE of the old row. For example, if column a is declared as UNIQUE and contains the value 1, the following two statements have similar effect*1:
                    INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1; UPDATE table SET c=c+1 WHERE a=1;
                    (The effects are not identical for an InnoDB table where a is an auto-increment column. With an auto-increment column, an INSERT*3 statement increases the auto-increment value but UPDATE*2 does not.)
                    *1 Die Ausage lautet: die folgenden Statements haben den gleichen Effekt, also das Insert und das Update. Dies gilt aber nicht für InnoDB.
                    *2 Unter innodb: Das oben aufgeführte Statement allein führt nicht zu einem AI Increase (natürlich nicht ist ja ein Update), das Insert statement tut es aber.

                    Das ist für mich die Aussage, die genau durch Deinen Fall wiedergespiegelt wird.
                    Und ich sehe das wie erc, so einen massiven Bug sollte es eigentlich nicht geben. Es ist (missverständlich) dokumentiertes Verhalten der InnoDB Engine.

                    Viel besser Deine Ideen ohne den Mist zu arbeiten, mach ein Update und wenn es leer läuft das Insert. Das wird keine viel größere Last produzieren, weil technisch eigentlich das fast gleiche abläuft, nur nicht so bequem gecodet.
                    Es hat den Vorteil, dass jedem der es ließt und anpackt, klar ist, was passiert.

                    Was die Ausfallerscheinungen angeht (manchmal geht es, manchmal nicht), dazu 2 Dinge:
                    1. Ich kann von hier aus nicht Deinen gesamten Code überblicken und ich muss aus Erfahrung sagen, dass oft Seiteneffekte aus anderen Richtungen übersehen werden. Du kannst natürlich sagen, alles ist wasserdicht, aber das glaube ich erst, wenn ich den kompletten Code mit der Umgebung und den Clients hier habe und prüfen kann. (Was nicht geschehen wird) oder Du umgekehrt autonom laufenden Code lieferst, der das Fehlerverhalten zeigt. (sqlFiddle oder entsprechende DDL, DML Scripte hier postest)
                    2. Wahrscheinlich werde ich dafür gesteinigt, aber: bei mysql würde es mich nicht wundern, wenn doch unter bestimmten Prämissen was schief läuft. Ich fasse diese Datenbank nicht ernsthaft an. Sie ist traditionell nicht so robust, wie man sich das vorstellt bbei einem Produktivsystem und hat ein paar lausige Ecken (andere würden das drastischer ausdrücken). Wenn man sie dennoch einsetzt (und sogar solche Dinge geschehen), dann jedenfalls das gesamte System auf bekannte mysql Probleme prüfen-sollte man sowieso. Alles was per Conf abstellbar ist und das System "sauberer" macht, hochdrehen. Funktionen wie diese hier meiden, usw, usf.

                    Kommentar


                    • #25
                      Zitat von Perry Staltic Beitrag anzeigen
                      2. Wahrscheinlich werde ich dafür gesteinigt, aber: bei mysql würde es mich nicht wundern, wenn doch unter bestimmten Prämissen was schief läuft.
                      Nö, warum, ist doch bekannt das das DBMS von Oracle stiefmütterlich behandelt wird und die lieber Geld verdienen. Aber solange das, die meist genutzte DB ist, muss man sich halt mit den Unzulänglichkeiten auseinandersetzen.

                      Stimme dir aber ansonsten zu, was die Lösung angeht um das Problem zu umschiffen.

                      Kommentar


                      • #26
                        Zitat von protestix Beitrag anzeigen
                        Nö, warum, ist doch bekannt das das DBMS von Oracle stiefmütterlich behandelt wird und die lieber Geld verdienen. Aber solange das, die meist genutzte DB ist, muss man sich halt mit den Unzulänglichkeiten auseinandersetzen.
                        Ja, das hat Oracle geschickt gemacht, Konkurrenzsystem kaufen (Csluster) und dann langsam verhungern lassen oder Support verkaufen. Allein dass es nun in Hand von Oracle ist, ist für mich unabhängig von der Qualität ein Grund es zu meiden. Alternativ kostenlos ORacle Express bis 10 GB, Geld ausgeben und Oracle Standard, sehr viel Geld für Enterprise oder
                        andere DB wie z.B: Postgresql für lau. Hier wird schon länger rasant entwickelt und die Features muss man teilweise fast als Genuss bezeichnen. Ja und robust ist es.

                        Kommentar

                        Lädt...
                        X