PHP - Subida de datos muy lenta

 
Vista:
sin imagen de perfil
Val: 13
Ha aumentado su posición en 16 puestos en PHP (en relación al último mes)
Gráfica de PHP

Subida de datos muy lenta

Publicado por Lorenzo (1 intervención) el 28/10/2019 17:02:17
Hola a todos, veréis tengo un problema con un script que estoy haciendo para mi empresa. Necesito abrir un archivo csv, leer x columnas y subirlas a la base de datos. El problema que tengo es que hace varias comprobaciones en los campos y esto ralentiza mucho la subida de información de hecho puede llegar a tardar hasta 3 horas para subir 47000 registros y eso no es viable. ¿Como puedo solucionar esto? Aquí os dejo el código para que le echéis un vistazo. Gracias de ante mano.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
if($columna[13] == 'csv'){
    while ($datos = fgetcsv($archivo, 0, ";")){
        $linea++;
        //Si la línea leída es igual o superior
        if ($linea >= $columna[2]) {
            //Compruebo si son numéricos
            if (preg_match('/[[:alpha:]]/i', str_replace(chr(0), '', $datos[$columna[3]])) == false) {
                //Si contienen datos
                if (str_replace(chr(0), '', $datos[$columna[3]]) != null) {
                    //Si el EAN es igual o mayor a 11 entra
                    if(strlen(str_replace(chr(0), '', $datos[$columna[3]])) >= 11){
                        //Si la cadena es menor de 13 se añaden 0 a la izquierda
                        if (strlen(str_replace(chr(0), '', $datos[$columna[3]])) < 13 ) {
                            $EAN = str_pad(str_replace(chr(0), '', $datos[$columna[3]]), 13, '0', STR_PAD_LEFT);
                        }else{
                            $EAN = str_replace(chr(0), '', $datos[$columna[3]]);
                        }
 
                        if($columna[4] == null){
                            $Mod = "";
                        }else{
                            $Mod = utf8_decode(str_replace(chr(0), '', $datos[$columna[4]]));
                        }
 
                        if(str_replace(chr(0), '', $datos[$columna[5]]) >= 0){
                            (int)$Stock = str_replace(chr(0), '', $datos[$columna[5]]);
                        }else{
                            $Stock = 0;
                        }
 
                        $Des = utf8_decode(str_replace(chr(0), '', $datos[$columna[6]]));
 
                        if($columna[7] == null){
                            $Marca = "";
                        }else{
                            $Marca = str_replace(chr(0), '', $datos[$columna[7]]);
                        }
 
                        $Familia = utf8_decode(str_replace(chr(0), '', $datos[$columna[8]]));
 
                        if($columna[9] == null){
                            $Peso = 0;
                        }else{
                            (float)$Peso = str_replace(',', '.', str_replace(chr(0), '', $datos[$columna[9]]));
                        }
 
                        (float)$Precio = str_replace(',', '.', str_replace(chr(0), '', $datos[$columna[10]]));
 
                        if($columna[11] == null){
                            $Canon = 0;
                        }else{
                            (float)$Canon = str_replace(',', '.', str_replace(chr(0), '', $datos[$columna[11]]));
                        }
 
                        if($columna[12] == null){
                            if($Precio < 200){
                                $Portes = 5;
                            }else{
                                $Portes = 0;
                            }
                        }else{
                            (float)$Portes = str_replace(',', '.', str_replace(chr(0), '', $datos[$columna[12]]));
                        }
 
                        (float)$PrecioTotal = $Precio + $Canon;
 
 
                        $insertar = "INSERT into dbo.portal_csv_proveedores_mayoristas (Proveedor,EAN,Modelo, Stock,Descripcion,Marca,Familia,Peso,Precio,Canon,Portes,PrecioTotal) values ('$columna[0]','$EAN','$Mod',$Stock,'$Des','$Marca','$Familia',$Peso,$Precio,$Canon,$Portes,$PrecioTotal)";
                        $sql = sqlsrv_prepare($conn, $insertar);
 
                        sqlsrv_execute($sql);
                    }//Fin if ean igual o mayor a 11
                }//Fin if null
            }//Fin if excluir letras
        }//Fin if linea 2
    }//Fin while
}//Fin if
 
//Cerramos el archivo
fclose($archivo);
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de joel
Val: 3.828
Oro
Ha mantenido su posición en PHP (en relación al último mes)
Gráfica de PHP

Subida de datos muy lenta

Publicado por joel (1269 intervenciones) el 28/10/2019 18:23:20
Viendo el código, me da la sensación que el problema puede estar en la base de datos? puede ser?
Has comprobado el rendimiento de SQL Server? o del servidor que lo contiene?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 13
Ha aumentado su posición en 16 puestos en PHP (en relación al último mes)
Gráfica de PHP

Subida de datos muy lenta

Publicado por Lorenzo (5 intervenciones) el 28/10/2019 18:35:13
He pensado lo mismo, pero resulta que el servidor donde está alojada la base de datos tiene recursos de sobra, también pensé que podría ser algo de la conexión pero tampoco hay problemas de velocidad, por eso pienso que el código tiene algún tipo de cuello de botella con tantos if y else.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de joel
Val: 3.828
Oro
Ha mantenido su posición en PHP (en relación al último mes)
Gráfica de PHP

Subida de datos muy lenta

Publicado por joel (1269 intervenciones) el 28/10/2019 19:58:25
No veo ningun bucle, ni se ver ninguna función que no sea de PHP, no?

Si quieres, puedes ir poniendo que te muestre el timestamp antes de cada if, así veras en que punto tarda mas...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 13
Ha aumentado su posición en 16 puestos en PHP (en relación al último mes)
Gráfica de PHP

Subida de datos muy lenta

Publicado por Lorenzo (5 intervenciones) el 29/10/2019 10:09:10
No hay nada aparte del php. Probaré a mostrar el timestamp a ver si los tiempos son "adecuados", gracias por la ayuda, ya que no se me había ocurrido. Ya comentaré los resultados.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 13
Ha aumentado su posición en 16 puestos en PHP (en relación al último mes)
Gráfica de PHP

Subida de datos muy lenta

Publicado por Lorenzo (5 intervenciones) el 29/10/2019 10:46:41
Bueno, el resultado es de 1 segundo cada 8 registros, el algunos momentos son algo más y otros algo menos, pero se mantiene sobre los 8 por segundo. Por lo que para mi parecer es una velocidad bastante correcta haciendo cuenta la cantidad de comprobaciones que hace. ¿Podría ser cosa de la velocidad de escritura?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 13
Ha aumentado su posición en 16 puestos en PHP (en relación al último mes)
Gráfica de PHP

Subida de datos muy lenta

Publicado por Lorenzo (5 intervenciones) el 05/11/2019 17:19:40
Al final conseguí solucionarlo, aunque no tanto como me gustaría, pero he conseguido pasar a 30 min de subida de datos de csv muy tochos. La solución ha sido la siguiente: Elimine algunos if, y los metí en uno solo, ya que esto me ralentizaba mucho, luego añadí alguna comparación más ya que sin ellas, el funcionamiento se estancaba un poco con algunos registros, ya que no las hacia correctamente. El código ha quedado tal que así. Por si en el futuro a alguien más le ocurre algo similar. Muchas gracias por la ayuda.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
if($columna[13] == 'csv'){
    while ($datos = fgetcsv($archivo, 4069, ";")){
        $linea++;
        //Si la línea leída es igual o superior a la tercera entonces se hacen las inserciones
        if ($linea >= $columna[2]) {
            //Compruebo si son numéricos, si contienen datos, si el ean es igual o mayor a 11, si tiene menos de 3 ceros a la izquierda y si no tiene signos de puntación
            if ((preg_match('/[^[:digit:]]/i', str_replace(chr(0), '', $datos[$columna[3]])) == false) && (str_replace(chr(0), '', $datos[$columna[3]]) != null) && (strlen(str_replace(chr(0), '', $datos[$columna[3]])) >= 11) && (substr(str_replace(chr(0), '', $datos[$columna[3]]),0,2) != '000') && (preg_match('/[[:punct:]]/i', str_replace(chr(0), '', $datos[$columna[3]])) == false)) {
                //Si la cadena es menor de 13 se añaden 0 a la izquierda
                if ((strlen(str_replace(chr(0), '', $datos[$columna[3]])) < 13) &&  (strlen(str_replace(chr(0), '', $datos[$columna[3]])) > 10)) {
                    $EAN = str_pad(str_replace(chr(0), '', $datos[$columna[3]]), 13, '0', STR_PAD_LEFT);
                }else{
                    $EAN = str_replace(chr(0), '', $datos[$columna[3]]);
                }
 
                if($columna[4] == null){
                    $Mod = "";
                }else{
                    $Mod = utf8_decode(str_replace(chr(0), '', $datos[$columna[4]]));
                }
 
                if(str_replace(chr(0), '', $datos[$columna[5]]) >= 0){
                    $Stock = str_replace(chr(0), '', $datos[$columna[5]]);
                }else{
                    $Stock = 0;
                }
 
                $Des = utf8_decode(str_replace(chr(0), '', $datos[$columna[6]]));
 
                if($columna[7] == null){
                    $Marca = "";
                }else{
                    $Marca = str_replace(chr(0), '', $datos[$columna[7]]);
                }
 
                $Familia = utf8_decode(str_replace(chr(0), '', $datos[$columna[8]]));
 
                if($columna[9] == null){
                    $Peso = 0;
                }else{
                    $Peso = str_replace(',', '.', str_replace(chr(0), '', $datos[$columna[9]]));
                }
 
                if(is_numeric(str_replace(',', '.', str_replace(chr(0), '', $datos[$columna[10]])))){
                    $Precio = str_replace(',', '.', str_replace(chr(0), '', $datos[$columna[10]]));
                }else{
                    $Precio = 0;
                }
 
                if($columna[11] == null){
                    $Canon = 0;
                }else{
                    $Canon = str_replace(',', '.', str_replace(chr(0), '', $datos[$columna[11]]));
                }
 
                if($columna[12] == null){
                    if($Precio < 200){
                        $Portes = 5;
                    }else{
                        $Portes = 0;
                    }
                }else{
                    $Portes = str_replace(',', '.', str_replace(chr(0), '', $datos[$columna[12]]));
                }
 
                $insertar = "INSERT into dbo.portal_csv_proveedores_mayoristas (Proveedor,EAN,Modelo, Stock,Descripcion,Marca,Familia,Peso,Precio,Canon,Portes) values ('$columna[0]','$EAN','$Mod',$Stock,'$Des','$Marca','$Familia',$Peso,$Precio,$Canon,$Portes)";
                $sql = sqlsrv_prepare($conn, $insertar);
 
                sqlsrv_execute($sql);
 
            }//Fin if excluir letras
        }//Fin if linea 2
    }//Fin while
}//Fin if
//Cerramos el archivo
fclose($archivo);
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
Imágen de perfil de Kathyu
Val: 1.802
Plata
Ha mantenido su posición en PHP (en relación al último mes)
Gráfica de PHP

Subida de datos muy lenta

Publicado por Kathyu (905 intervenciones) el 05/11/2019 17:32:48
Osea que lo lento es la comprobación del archivo no la subida a la DB en si??
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 13
Ha aumentado su posición en 16 puestos en PHP (en relación al último mes)
Gráfica de PHP

Subida de datos muy lenta

Publicado por Lorenzo (5 intervenciones) el 06/11/2019 10:20:50
Exacto, por lo visto el scrip se volvía un poco loco, ya que algunos registros presentaban errores en los ficheros de origen y hacia que algunas comprobaciones no se ejecutaran correctamente, además el tener varios if anidados me hacia que la velocidad se redujera, por lo que en ciertas comprobaciones pude dejarlas todas en una "sola" comprobación. Aún así, pienso que si el servidor tuviera ssd en vez de un hdd convencional esta velocidad también se aumentaría.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar