2016-04-26 7 views
2

Wir haben unsere DB-Verbindung von ADODB zu SQLSRV geschaltet und ich habe Probleme damit intermittierende Verzögerungen mit sqlsrv_fetch_array verursachen.PHP SQLSRV hat intermittierende Verzögerung auf sqlsrv_fetch_array/sqlsrv_fetch

Ich mache eine Abfrage in meiner Datenbank, die rund 426 Zeilen mit 5 Feldern zurückgibt.

Der Code sieht wie folgt aus (für Geschwindigkeit Benchmark Zwecke ich wirklich entfernt alles, was es tat):

$conn = sqlsrv_connect($host, array("UID"=>$userName,"PWD"=>$password,"Database"=>$dbName,"QuotedId"=>false, "CharacterSet" =>"UTF-8"); 

$rsText=sqlsrv_query($conn,$sqlStr,array(), 
       array(
        "Scrollable"=>SQLSRV_CURSOR_STATIC 
       )); 

$row = array(1); 
while(count($row) != 0){ 
    $row=sqlsrv_fetch_array($rsText,SQLSRV_FETCH_BOTH, SQLSRV_SCROLL_NEXT); 
} 

Laufen dies mit ADODB mir dauert etwa 50 ms. Es mit sqlsrv laufen zu lassen dauert zwischen 500-1000ms. Die ursprüngliche Abfrage (sqlsrv_query) ist tatsächlich schneller mit sqlsrv als ADODB, aber es gibt zufällige Zeitverzögerungen mit der sqlsrv_fetch_array (ich habe tatsächlich mit sqlsrv_fetch getestet und auch erhalten). Ich habe jeden Anruf in ms gemessen, und während es normalerweise 0-1ms pro Anruf ist, ist es manchmal bis zu 15ms. Warum ich sage, dass es zufällig ist, dass, wenn ich den Code mehrmals wiederhole, die Verzögerungen nicht am selben Ort auftreten und in den Zahlen variieren, so ist es nicht, weil eine bestimmte Zeile groß ist (was auch keiner von beiden ist) .

Hat jemand eine Idee darüber, was ich sehen könnte, könnte dies tun, sei es ein Parameter oder eine Konfiguration irgendwo? Ich glaube nicht, dass es server/netzwerkbezogen ist, da ADODB dies nie tut. Wir verwenden PHP 5.6 und die php_sqlsrv_56_ts.dll/php_pdo_sqlsrv_56_ts.dll und SQL Server 2008.

Vielen Dank!

+0

Wie wäre es mit verschiedenen Abruf- und Scroll-Typen? Zum Beispiel, verlassen sie mit Standard-Parameter, was ist das Zeitintervall? Sieht so aus, als ob es um einige Underhood-Operationen in der DLL geht. – alalp

+0

Vielen Dank für den Vorschlag, den Scroll-Typ zu ändern funktioniert! Es scheint, dass SQLSRV_CURSOR_STATIC das Problem war. Ich habe alle Optionen ausprobiert, und SQLSRV_CURSOR_FORWARD gibt die gleiche Geschwindigkeit wie ADODB. Sie verlieren die Fähigkeit, sich zuerst/rückwärts zu bewegen, aber das ist kein großes Problem. SQLSRV_CURSOR_CLIENT_BUFFERED geht extrem schnell, weist jedoch in einigen Fällen Speicherprobleme auf.Alle anderen Optionen, die das Vor- und Zurückgehen ermöglichen, haben das gleiche Problem wie SQLSRV_CURSOR_STATIC in Bezug auf die Geschwindigkeit, also muss etwas da sein. Wenn Sie dies als Antwort schreiben möchten, werde ich es akzeptieren. – user3242224

+0

Sie können Ihre eigene Antwort hinzufügen, weil Sie sie getestet haben und Sie mehr darüber wissen. Ich möchte deinen Kommentar nicht einfach kopieren und einfügen :) – alalp

Antwort

0

Wie von alalp in den Kommentaren vorgeschlagen, habe ich versucht, den Scroll-Typ zu ändern und das Problem behoben.

Ich habe einige schnelle Benchmark und hier ist, was ich habe:

SQLSRV_CURSOR_STATIC, SQLSRV_CURSOR_KEYSET und SQLSRV_CURSOR_DYNAMIC: schwere Geschwindigkeit Problem. Wie im ursprünglichen Beitrag erwähnt, würde das Schleifen von selbst einer moderaten Anzahl von Datensätzen (einige 100) eine Sekunde dauern.

SQLSRV_CURSOR_FORWARD: keine Geschwindigkeitsproblem. Es dauerte etwa 50ms, um die Datensätze meines Beispiels zu durchlaufen, das mit ADODB identisch war. Sie haben die Möglichkeit, MoveFirst/MovePrev zu verwenden, aber ich denke, dies lässt sich leicht beheben, indem Sie die Ergebnisse bei Bedarf im ersten Durchgang in einem Array speichern oder je nach Abfrage in den seltenen Fällen, in denen dies der Fall ist erforderlich.

SQLSRV_CURSOR_CLIENT_BUFFERED: schnell prallen (0 ms in meinem Beispiel, was es ist im Grunde die gleiche wie die ganze Sache in einem Array zu speichern Sinn, weil aus meinem Verständnis macht). Wir hatten jedoch Speicherprobleme in einigen größeren Datasets.

In unserem Projekt verwendeten wir SQLSRV_CURSOR_CLIENT_BUFFERED für die öffentliche Website, weil auf keiner Seite jemals ein Hauptdatensatz extrahiert wurde, und SQLSRV_CURSOR_FORWARD für das Back-End, bei dem Sie Tausende von Datenzeilen ziehen können.