susi: mysql_query() in php speicher?

hallo,

ich ahb nur eine kurze frage zur bestätigung gesucht!
mysql_query() ladet das result nicht in den php speicher sondern rein in den DB_cach oder?
da ich ja mit mysql_fetch_array immer nur einen datensatz aus der DB hole? hab ich dies richtig verstanden?
also belegt mir $result mysql_fetch_array(??)
immer nur den speicher für den momentanen datensatz, oder?
wenn ich jedoch jeden datensatz will müsste ich array_push in die übliche while schleife des mysql_fetch_array schreiben, ai?

lg susi

  1. mysql_query() ladet das result nicht in den php speicher sondern rein in den DB_cach oder?

    query ermittelt nur die betroffenenen zeilen einer tabelle. die zeilen werden nicht gelesen.

    da ich ja mit mysql_fetch_array immer nur einen datensatz aus der DB hole? hab ich dies richtig verstanden?

    fetch holt die aktuellen eine zeile aus der tabelle.

    also belegt mir $result mysql_fetch_array(??)
    immer nur den speicher für den momentanen datensatz, oder?

    immer nur speicher für eine zeile.

    wenn ich jedoch jeden datensatz will müsste ich array_push in die übliche while schleife des mysql_fetch_array schreiben, ai?

    du kopierst die eine zeile in einen teil deines programmes.

  2. Hello,

    mysql_query() holt das gesamte Abfrageergebnis in einen Buffer.
    Ob der nun zum Bereich von MySQL oder zum Bereich von PHP gehört, kann ich Dir auch nicht aus dem Handgelenk beantworten.

    mysql_unbuffered_query() holt jedenfalls nur jeweils eine Zeile des Ergebisses in den Zuständigkeitsbreich von PHP.

    http://de3.php.net/manual/de/function.mysql-unbuffered-query.php

    Harzliche Grüße aus http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau
    1. Hi!

      mysql_query() holt das gesamte Abfrageergebnis in einen Buffer.
      Ob der nun zum Bereich von MySQL oder zum Bereich von PHP gehört, kann ich Dir auch nicht aus dem Handgelenk beantworten.

      Die Daten werden erstmal komplett zum Client (Prozess der PHP-Code ausführt) übertragen. Dann greifen andere mysql_* Funktionen auf diese lokalen Daten zu. PHP/MySQL kann man hier halt nicht wirklich trennen, sondern nur Client/Server. Veranwortlich hierfür ist die MySQL-Extension für PHP, die die C-API von MySQL verwendet.

      Grüße
      Andreas

      --
      SELFHTML Linkverzeichnis: http://aktuell.de.selfhtml.org/links/
      1. Die Daten werden erstmal komplett zum Client (Prozess der PHP-Code ausführt) übertragen. Dann greifen andere mysql_* Funktionen auf diese lokalen Daten zu. PHP/MySQL kann man hier halt nicht wirklich trennen, sondern nur Client/Server. Veranwortlich hierfür ist die MySQL-Extension für PHP, die die C-API von MySQL verwendet.

        das ist ja interessant. habe ich mir bisher keine gedanken drum gemacht, da ich hauptsächlich mit db2 und oracle zu tun habe. die machens definitiv nicht so.

        allerdings ist dieses vorgehen aber auch nachteilig. es erhöht die antwortzeiten und kann bei ungewollt großen ergebnissen zu abstürzen wegen speichermangels führen. es wäre daher wohl angebracht, erst einmal mit count() die ergebnismenge zu checken.
        daher ist auch die praktische limit möglichkeit zu erklären.

        was passiert eigentlich bei 'blätterseiten', wo aus der ergebnismenge ein bereich per limit ausgewählt wird. holt mysql dort auch erst die komplette ergebnismenge gemäß der bedingung ?

        1. Hello,

          was passiert eigentlich bei 'blätterseiten', wo aus der ergebnismenge ein bereich per limit ausgewählt wird. holt mysql dort auch erst die komplette ergebnismenge gemäß der bedingung ?

          Limit ist ja ein Feaature von MySQL, und damit glasklar der Obhut des DBMS zuzurechnen. Es werde dann nur die Zeilen esportiert, die betroffen sind.

          Harzliche Grüße aus http://www.annerschbarrich.de

          Tom

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau
          1. Limit ist ja ein Feaature von MySQL, und damit glasklar der Obhut des DBMS zuzurechnen. Es werde dann nur die Zeilen esportiert, die betroffen sind.

            der wesentliche vorteil des limit ist der offset. bei db2 und oracle gibts dies nicht, sondern nur top oder first. daher muß man dort schon mit tricks arbeiten, wenn man die offset möglichkeit braucht. dabei werden aber immer alle zeilen (mit subselects) angesprochen.

            aber hier war ja die frage, ob query bereits die daten der zeilen in den speicher bringt. würde mysql (unabhängig von php) dies bereits tun, müßten alle zeilen gemäß der bedingung im speicher sein. dort würde dann limit ansetzen.
            dies kann ich aber nicht glauben. dies würde zuviel overhead und ressourcen kosten. daher glaube ich, daß mysql nach dem query maximal eine pointer-liste auf die zeilen hat, welche mit limit adressiert werden. erst beim fetch holt mysql die zeile in den speicher.

            mag sein daß das angesprochene php-myslq-api bereits nach query alle daten der betroffenen zeilen (auch mit limit) abholt, (diese wären dann auf jeden fall im php-prozeß) und mit php-mysql-api-fetch aus dem php-prozeß bereitstellt. klingt für mich aber auch sehr merkwürdig.
            wahrscheinlicher scheint mir, daß auch dort nur eine pointer-liste existiert, welche möglicherweise mit php-query in den php-prozeß geholt wird, und beim php-fetch der pointer an mysql zum holen der daten der zeile gegeben wird.

            mit einem kleinen test ließe sich möglicherweise mehr klarheit verschaffen:

            1. update tabelle set wert = wert1
            2. query select tabelle (wenn daten der zeilen jetzt schon im speicher müßte wert1 sein)
            3. update tabelle set wert = wert2
            4. schleife um fetch (wenn daten der zeilen bereits im speicher müßte wert1 sein)
            wenn jetzt aber wert2 ist, hat fetch die daten erst jetzt geholt.

            nach meinem urlaub mache ich mal son test.

            1. Hello,

              aber hier war ja die frage, ob query bereits die daten der zeilen in den speicher bringt.

              Dass nur eine Pointer-Liste gehalten wird in MySQL halte ich (ohne jetzt reingeguckt zu haben) für unwahrscheinlich, da es dann in stark bewegten Datenbeständen entsprechende Differenzen geben müsste und es auch schon mal vorkommen würde, dass der Datensatz beim tatsächlichen abholen nicht mehr vorhanden ist.

              MySQL wird also beim Limit den gesamten gefilteten Datenbereich in den Speicher (des MySQL-Servers) holen

              Harzliche Grüße aus http://www.annerschbarrich.de

              Tom

              --
              Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
              Nur selber lernen macht schlau
              1. Dass nur eine Pointer-Liste gehalten wird in MySQL halte ich (ohne jetzt reingeguckt zu haben) für unwahrscheinlich, da es dann in stark bewegten Datenbeständen entsprechende Differenzen geben müsste und es auch schon mal vorkommen würde, dass der Datensatz beim tatsächlichen abholen nicht mehr vorhanden ist.

                mysql ist halt nicht transaktionssicher.

                MySQL wird also beim Limit den gesamten gefilteten Datenbereich in den Speicher (des MySQL-Servers) holen

                merkwürde schlußfolgerung (auf spekulation basierend: MySQL halte ich (ohne jetzt reingeguckt zu haben)

                gewißheit bringt nur ein test

                1. Hello,

                  merkwürde schlußfolgerung (auf spekulation basierend: MySQL halte ich (ohne jetzt reingeguckt zu haben)

                  gewißheit bringt nur ein test

                  gestestet habe ich das schon sehr oft zur Erstellung von kempletten Vorgangsbearbeitungen und nicht zuletzt immer noch meinen Self-Artikel zum Thema Locking.

                  Abfragen bei MySQL sind Snapshots und keine Dynasets, um jetzt mal mit M$-Sprache zu sprechen.

                  Harzliche Grüße aus http://www.annerschbarrich.de

                  Tom

                  --
                  Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                  Nur selber lernen macht schlau
        2. Hallo!

          was passiert eigentlich bei 'blätterseiten', wo aus der ergebnismenge ein bereich per limit ausgewählt wird. holt mysql dort auch erst die komplette ergebnismenge gemäß der bedingung ?

          Nein. Die Query wird so wie sie angegeben wird (inkl. LIMIT...) an den MySQL-Server übertragen. Dieser führt die Query aus. Wenn Du LIMIT angibst, wird schon auf dem Server entsprechend LIMIT gefiltert. Das Ergebnis wird dann komplett an die Client-Applikation (PHP-Prozess) übertragen. Wenn Du z.B. 1.000.000 Datensätze in der Tabelle hast und Du das Ergebnis mit LIMIT auf 100 Datensätze begrenzt, werden entsprechend nur diese 100 Datensätze vom Server an den Client übertragen. Dann kannst Du mit den passenden PHP-Funktionen diese 100 Datensätze abfragen, man kann sich sogar in den lokalen Datensätzen frei vor und zurück "bewegen".

          Grüße
          Andreas

          --
          SELFHTML Linkverzeichnis: http://aktuell.de.selfhtml.org/links/
          1. wo bewegt sich das LIMIT? wenn bspw. der offset 5678901 in dem ergebnis ist. ich hatte das ja schon mal in dem anderen post angesprochen.
            dann muß mysql oder auch jede andere db-engine ja einen scope über alle zeilen haben und die offset zeilenmenge verwerfen. das wäre dann zwar innerhalb mysql und hat nichts mit php zu tun, ist aber trotzdem interessant.

            in bezug auf php würde die mit limit begrenzte zeilenzahl geliefert. das limit könnte ja bspw. von offset 123456 eine anzahl von 654321 sein. dann würde php ja schon mit query eine ganze menge an daten abholen, welche ja auch im speicher stehen müßten. dies ist schwer vorstellbar, und die fetch und cursor von php-mysql würden sich nur auf diesen speicher beziehen.

            die angesprochene cursormöglichkeit setzt allerdings keine komplett gelesenen ergebniszeilen voraus. mag bei php-mysql anders sein, bei db2 und oracle zumindest ist dem nicht so. dort steht nur eine pointer-liste zu den ergebniszeilen, auf welchem sich der cursor bewegt. erst beim fetch wird die datenzeile gelesen. diese db2 werden aber idr. auf 'großen' systemen eingesetzt. das php-mysql vorgehen wäre dort aus performance und speichergründen nicht möglich.

            1. Hallo!

              wo bewegt sich das LIMIT? wenn bspw. der offset 5678901 in dem ergebnis ist. ich hatte das ja schon mal in dem anderen post angesprochen.
              dann muß mysql oder auch jede andere db-engine ja einen scope über alle zeilen haben und die offset zeilenmenge verwerfen. das wäre dann zwar innerhalb mysql und hat nichts mit php zu tun, ist aber trotzdem interessant.

              Wie genau das bei MySQL implementiert ist, kann man wohl im Source nachlesen, das habe ich mir noch nie angesehen. Ein paar Sätze stehen dazu auch in der Doku: http://dev.mysql.com/doc/mysql/en/limit-optimization.html..., naja.

              Jedenfall ist der Sinn von SQL ja unter anderem, die Komplexität eines performanten Zugriffs bzw. Filterung aus großen Datenmengen vor den Anwendern zu verstecken. Je nach Daten und Filterung ist nicht immer dieselbe Zugriffsmethode die schnellste. RDBMS sind halt darauf spezialisiert, einen möglichst effizienten Weg zu benutzen, die gewünschten Daten zu extrahieren. Das klappt nicht immer so wie gewünscht, daher schadet es sicher nicht zu wissen wie die eingesetzte Datenbank optimiert und wie man diese Optimierung ggfs. beeinflussen kann.

              in bezug auf php würde die mit limit begrenzte zeilenzahl geliefert. das limit könnte ja bspw. von offset 123456 eine anzahl von 654321 sein. dann würde php ja schon mit query eine ganze menge an daten abholen, welche ja auch im speicher stehen müßten.

              Ja. Das gibt (je nach Umfang der Daten) dann mit Sicherheit Probleme, meist mit dem memory_limit von PHP. Allerdings ist das - gerade im Web - ein Sonderfall, der nicht wirklich häufig vorkommt. MySQL ist für viele einfache Anwendungsfälle sicher eine gute Lösung, das trifft gerade auf Web-Anwendungen oft zu. Wenn das dann aber nicht reicht gibt es ja noch genügend andere Datenbanken, die bessere Ansätze für den speziellen Fall verfolgen. Bei MySQL könnte man sich mit einer explizit ungepufferten Query behelfen, wie Tom es verlinkt hat. In diesem Fall wird auch jeder Datensatz direkt geholt.

              Grüße
              Andreas

              --
              SELFHTML Feature Artikel: http://aktuell.de.selfhtml.org/artikel/
            2. bei db2 und oracle zumindest ist dem nicht so. dort steht nur eine pointer-liste zu den ergebniszeilen, auf welchem sich der cursor bewegt. erst beim fetch wird die datenzeile gelesen.

              Bedeutet das, das Änderungen eines zweiten Users sofort durchschlagen? Also Zeile 1 zeigt mir die Daten zum Zeitpunkt x, Zeile 2 zum Zeitpunkt y?

              Klingt komisch ...

              LG Kalle

              1. Bedeutet das, das Änderungen eines zweiten Users sofort durchschlagen? Also Zeile 1 zeigt mir die Daten zum Zeitpunkt x, Zeile 2 zum Zeitpunkt y?

                db2 und oracle sind transaktionssicher. (stichwort commit)

              2. Hello,

                bei db2 und oracle zumindest ist dem nicht so. dort steht nur eine pointer-liste zu den ergebniszeilen, auf welchem sich der cursor bewegt. erst beim fetch wird die datenzeile gelesen.

                Bedeutet das, das Änderungen eines zweiten Users sofort durchschlagen? Also Zeile 1 zeigt mir die Daten zum Zeitpunkt x, Zeile 2 zum Zeitpunkt y?

                Klingt komisch ...

                Das hängt davon ab, was man angefordert hat. Bei M$ heißen die beiden Kandidaten "Snapshot" und "Dynaset". Ein Snapshot liefert eine Selection zum Zeitpunkt x, während ein Dynaset nur die Regeln für die Selection vom Zeitpunkt x konserviert und sich den Zeiger auf das Element der Menge merkt. Jedes "Atom", hier also jeder Datensatz, bleibt aber für sich eigenständig.

                Wenn man andere am Ändern der Sätze während der eigenen Bearbeitung hindern will, muss man mit Satzsperren arbeiten.

                Harzliche Grüße aus http://www.annerschbarrich.de

                Tom

                --
                Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                Nur selber lernen macht schlau