Benutzer mit den meisten Antworten
PHP/MS SQL Server - Befehl sqlsrv_fetch_array

Frage
-
Hallo zusammen,
ich suche dringend jemanden, der sich mit dem Zusammenspiel PHP - Microsoft SQL Server auskennt.
Ich benutze momentan die folgenden Komponenten:
- Windows Server 2003/2008
- PHP 5.3.8
- Microsoft SQL Server 2005 Developer Edition
- Microsoft SQL Server 2008 R2 Native Client
- Microsoft SQL Server Treiber für PHP (verwendete Treiberdatei: php_sqlsrv_53_ts_vc9.dll)
Ich möchte mir per SELECT-Anweisung ca. 300 Datensätze aus der Datenbank ziehen.
Das ist ja nun nicht gerade spektakulär, sollte man meinen.
Wenn ich die Abfrage direkt im SQL Server Management Studio ausführe, dauert es ca. 1 Sekunde, bis ich das Ergebnis angezeigt bekomme.
Aus dem PHP-Code heraus dauert es 1 Minute und länger.Ich habe bei der Ausführung des PHP-Codes die Zeit gestoppt und kann definitiv sagen, dass das Auslesen per while-Schleife so lange dauert.
Hier mein Code:
$var_container = sqlsrv_query($var_connection, $var_sql, array(), array( "Scrollable" => SQLSRV_CURSOR_KEYSET ));
while($var_row = sqlsrv_fetch_array($var_container))
{
// Auslesen der Daten (8 Felder).
}Ich habe die Zeit gemessen
- die die komplette Schleife benötigt,
- die für einen Datensatz benötigt wird,
- die zwischen den Datensätzen anfällt.
Ich weiß definitiv, dass der Befehl sqlsrv_fetch_array das Problem ist.
Nun wüsste ich gerne, ob es eine schnellere Methode gibt, per SELECT Datensätze aus der Datenbank zu holen.
Freue mich über Feedback und Tipps.
Gruß
Thomas
Antworten
-
Hallo Thomas,
wenn Du die Daten direkt verarbeitest, solltest Du als "Cursor" den Standardtyp SQLSRV_CURSOR_FORWARD verwenden,
da dies für reines Lesen der schnellste Cursortyp ist - wie es das SSMS nebenbei auch tut.
Denn ein Keyset Cursor bedeutet größeren Aufwand, da zunächst alle Kandidatenschlüssel ermittelt werden,
was - insbesondere bei Fehlen eines passenden Index - deutlich mehr Zeit in Anspruch nehmen kann.
Weitere Erläuterungen zu den Cursortypen findest Du unter DECLARE CURSORGruß Elmar
- Als Antwort markiert tommy_schroeder Dienstag, 20. November 2012 08:18
Alle Antworten
-
Hallo Thomas,
wenn Du die Daten direkt verarbeitest, solltest Du als "Cursor" den Standardtyp SQLSRV_CURSOR_FORWARD verwenden,
da dies für reines Lesen der schnellste Cursortyp ist - wie es das SSMS nebenbei auch tut.
Denn ein Keyset Cursor bedeutet größeren Aufwand, da zunächst alle Kandidatenschlüssel ermittelt werden,
was - insbesondere bei Fehlen eines passenden Index - deutlich mehr Zeit in Anspruch nehmen kann.
Weitere Erläuterungen zu den Cursortypen findest Du unter DECLARE CURSORGruß Elmar
- Als Antwort markiert tommy_schroeder Dienstag, 20. November 2012 08:18
-
Hallo Elmar,
danke für den Tipp. Aber: Ich benötige SQLSRV_CURSOR_KEYSET, damit ich weiß, wieviele Datensätze ich bekomme. Das frage ich ab mit
sqlsrv_num_rows($var_container)
Wenn ich SQLSRV_CURSOR_FORWARD verwenden soll, wie bekomme ich dann VOR dem Auslesen heraus, um wieviele Datensätze es sich handelt, bzw. ob die SELECT-Abfrage überhaupt einen Datensatz liefert.
Gruß
Thomas -
Hallo Tommy,
läuft deine Anwendung ggfs. im Debugmodus? (Keine Ahnung, ob es sowas für PHP gibt, wenn man bspw. ASP.NET im Debugmode laufen lässt, kommt man auch manchmal auf sehr "merkwürdige" Ergebnisse, was die Laufzeit einzelner Befehle angeht)
Um eine Idee zu bekommen, woran es liegen könnte, müsstest Du uns sagen, wie dein SQL Statement aussieht und vor allem, wie die ausgelesenen Inhalte aussehen, bzw. welchen Datentyp die Spalten haben.
Einen Test kannst Du noch machen, nämlich die Schleife durchlaufen, aber eben nichts auslesen (einfach nur die Datensätze durchlaufen ohne ein Feld anzusprechen). Wenn das auch solange dauert, liegt es zumindest nicht an den Daten bzw. den Methoden, mit denen Du diese ausliest. In dem Fall wäre ggfs. ein clientseitiger Cursor besser, siehe dazu:
http://msdn.microsoft.com/en-us/library/hh487160.aspx
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Hallo Elmar, Hallo Stefan,
ich gebe Euch da vollkommen recht. Der Input war ein wenig dürftig.
Es hat sich aber in der Zwischenzeit etwas getan.
Ich bin zu dem Ergebnis gekommen, dass es mir in den meisten Fällen reicht, wenn ich weiß, ob mir die SELECT-Abfrage überhaupt einen Datensatz zurückliefert. Und das kann ich vorher in jedem Fall erfragen, und zwar bei allen drei Cursorn.
Bedeutet, ich benötige vor dem Auslesen doch nicht unbedingt die genaue Anzahl der Datensätze. Ich komme also mit SQLSRV_CURSOR_FORWARD prima zurecht, zumindest in den meisten Fällen.
Ich habe gestern und heute einige Performance-Tests gemacht, und zwar mit
- Microsoft Drivers for PHP for SQL Server 2.0 und SQLSRV_CURSOR_KEYSET.
- Microsoft Drivers for PHP for SQL Server 2.0 und SQLSRV_CURSOR_STATIC.
- Microsoft Drivers for PHP for SQL Server 2.0 und SQLSRV_CURSOR_FORWARD.
- ADODB Library for PHP5/ODBC.
SQLSRV_CURSOR_FORWARD bringt mir von der Geschwindigkeit her am meisten.
Übrigens sind es genau 275 Datensätze (und 15 Spalten).
Ich vermute aber, es lässt sich doch noch etwas optimieren. Vielleicht ist ja das Befüllen des PHP-Arrays ein Flaschenhals.
Wenn ich die Abfrage direkt im SQL Server Management Studio starte, kommt das Ergebnis in einer Sekunde.
Wisst Ihr zufällig, ob ich beim Befüllen eines PHP-Arrays dieser Größe (Spalte für Spalte und Zeile für Zeile) irgendetwas beachten muss?
Gruß Thomas
- Bearbeitet tommy_schroeder Dienstag, 3. April 2012 08:11