Matthias: Performance bei Textzerlegung

Beitrag lesen

Hallo,

schon mal Danke für die Denkanstoesse.

Hier als Beispiel eine Zeile aus der Datei. Mit explode oder regex wüsste ich nicht wie ich da rangehen soll.

1002201000000111110000000000  0000000815            73020100  000000000051,10 WARENSEND KLEINTEIL   Herr Müller         Nr.12345LiefSch231

Die Sache mit mit den substrings mit bestimmten Start- und Endpunkten ist hier die nach wie vor die einzige Lösung die mir einfällt.

Ich habe

  
$datei_daten = file( $this->datei_path.$this->datei_name );  
  
        foreach ( $datei_daten as $nr => $zeile )  

ausgetauscht mit

  
$handle = fopen ( $this->datei_path.$this->datei_name , "r" );  
        $nr     = '0';  
        while ( ! feof( $handle ) )  
        {  
  
          $nr++;  
          $zeile = fgets( $handle, '4096' );  

, das brachte schonmal eine Ersparnis von 2 Sekunden.

Dann habe ich mir die Geschichte mit Prepared-Statements angeschaut, das hatte dann aber länger gedauert. Muss mich da nochmal ein bisschen einlesen...

Ich habe, aufgrund des Hinweises, dass die lange Zeit mit durch die vielen Insert-Statements bedingt ist, meine Logik wie folgt geändert:

  
$handle = fopen ( $this->datei_path.$this->datei_name , "r" );  
$nr     = '0';  
$i      = '0';  
$query  = '';  
while ( ! feof( $handle ) )  
{  
  $nr++;  
  $i++;  
  $zeile = fgets( $handle, '4096' );  
  
  //Leerzeilen abfangen  
  if ( strlen ( trim( $zeile ) ) > '0' )  
  {  
    $A =               substr( $zeile ,   '0' ,  '8' );  
    $B =        ltrim( substr( $zeile ,   '8' , '10' ) , '0' );  
    $C =        ltrim( substr( $zeile ,  '18' , '12' ) , '0' );  
    $D =        ltrim( substr( $zeile ,  '30' , '10' ) , '0' );  
    $E =        ltrim( substr( $zeile ,  '40' , '12' ) , '0' );  
    $F =        ltrim( substr( $zeile ,  '52' , '10' ) , '0' );  
    $G = strtr( ltrim( substr( $zeile ,  '62' , '15' ) , '0' ) , ',' , '.' );  
    $H =         trim( substr( $zeile ,  '77' , ' 1' )       );  
    $I =        rtrim( substr( $zeile ,  '79' ,  '9' ) , ' ' );  
    $J =         trim( substr( $zeile ,  '88' , '10' )       );  
    $K =         trim( substr( $zeile ,  '99' , '20' )       );  
    $L =         trim( substr( $zeile , '120' ,  '8' )       );  
    $M =         trim( substr( $zeile , '128' , '20' )       );  
  
    $query .= "INSERT INTO  "  
             ."  table_name "  
             ."  (          "  
             ."    id,      "  
             ."    FieldA,  "  
             ."    FieldB,  "  
             [...]  
             ."    FieldM   "  
             ."  )          "  
             ."VALUES       "  
             ."  (          "  
             ."    '$nr',   "  
             ."    '$A',    "  
             ."    '$B',    "  
             [...]  
             ."    '$M'     "  
             ."  )          ";  
  
    if ( $i == '300' )  
    {  
      $query  = rtrim( $query , ';' );  
      $result = sqlsrv_query( $this->DB_Connector, $query );  
      $query  = '';  
      $i      = '0';  
      echo "<br><br>$nr/$i -> [$query]";  
    }  
  }  
}  
fclose ($handle);  
if ( strlen( $query ) > '0' )  
{  
  $query = rtrim( $query , ';' );  
  $result = sqlsrv_query( $this->DB_Connector, $query );  
  echo $this->db_error( $result , $query );  
}  

Erst hatte ich $query befüllt, und dann in einem Mal am Ende an SQL übergeben. Dabei waren aber jeweils nur ~250 Datensätze in der Tabelle, deswegen habe ich noch den Schritt eingebaut, dass nach 300 Sätzen ein Insert erfolgt, und $query wieder geleert wird.