Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Proceso demasiado lento (https://www.clubdelphi.com/foros/showthread.php?t=78758)

ErYcK 15-05-2012 11:28:26

Proceso demasiado lento
 
Buenas, he creado una aplicación con c++ builder 6 que lee un archivo csv y lo carga en un Memo, despues revisa una base de datos en access 2007 para comprobar que los datos de este csv no esten en la base de datos y los va introduciendo, mi problema es que manejo demasiada cantidad de datos , actualmente son unos 9000 registros, con lo cual, al recorrer la base de datos con cada inserción me tarda demasiado, no se como agilizar este proceso y si alguno tiene alguna idea de como hacer que esto sea mas rapido me seria de gran ayuda, gracias de antemano :).

Casimiro Notevi 15-05-2012 11:36:35

Tu explicación es muy genérica, deberías explicar ampliamente cómo lo haces, poner código, etc.

ErYcK 15-05-2012 11:57:50

OK ahi va el codigo:

Código:

void __fastcall TXPrincipal::ToolButton2Click(TObject *Sender)
{

        if(OpenDialog1->Execute())
        {
                int col =0;
                int cont=0;
                String referencia ="";
                Memo1->Lines->LoadFromFile(OpenDialog1->FileName);
                //Muestro la con un ProgressBar la carga de un StringGrid donde organizo los datos del Memo
                XCarga->Show();
                XCarga->ProgressBar1->Min = 0;
                XCarga->ProgressBar1->Max = Memo1->Lines->Count;
                for (int i =0; i <= Memo1->Lines->Count; i++)
                {
                        XCarga->ProgressBar1->Position = i;

                        for (int j=1; j<= Memo1->Lines->Strings[i].Length();j++)
                        {

                                if (Memo1->Lines->Strings[i][j] == ';')
                                {
                                        if (referencia != "")
                                                StringGrid1->Cells[col][i] = referencia;
                                        referencia = "";
                                        col++;
                                        cont++;
                                        if (cont>60)
                                        {
                                                cont =0;
                                                col=0;
                                                break;
                                        }
                                }
                                if (Memo1->Lines->Strings[i][j] != ';')
                                {
                                        referencia = referencia +Memo1->Lines->Strings[i][j];
                                }

                        }

                }
        }
        // StringGrid Cargado
        XCarga->Close();
        XDatos->TCategorias->Open();
        XDatos->TSubCat1->Open();
        XDatos->TSubCat2->Open();
        XDatos->TSubCat3->Open();
        XDatos->TMarcas->Open();
        XDatos->QRecorreProductos->Open();
        XDatos->TCaracteristicas->Open();
        // abro las tablas y consultas que voy a necesitar
        bool existe = false;
        int cont=0;
        XCarga->Show();
        XCarga->ProgressBar1->Min = 1;
        XCarga->ProgressBar1->Max = StringGrid1->RowCount;
        //Recorro el StringGrid
        for (int f=1;f<=StringGrid1->RowCount;f++)
        {
                XCarga->ProgressBar1->Position = f;
                existe = false;
                XDatos->QRecorreProductos->First();
                //Recorro la tabla de productos con una Query para comprobar que el producto no este ya en la BD   
                while (!XDatos->QRecorreProductos->Eof)
                {
                        if (XDatos->QRecorreProductosREFERENCIA->Value == StringGrid1->Cells[0][f])
                                    existe = true;
                        XDatos->QRecorreProductos->Next();
                }

            if (!existe && StringGrid1->Cells[0][f]!="")
            {
            // Si no existe ya y el campo del StringGrid correspondiente a la referencia no esta vacio
            // Comienzo a asignar valores al nuevo producto
                        XDatos->QProductos->Append();
                        XDatos->QProductosREFERENCIA->Value = StringGrid1->Cells[0][f];
                        XDatos->QProductosESTADO->Value = StringGrid1->Cells[1][f];
                        bool esta=false;
                        XDatos->TCategorias->First();
                        // compruebo k la categoria exista, si no es asi la añado   
                        while(!XDatos->TCategorias->Eof)
                        {
                                if (StringGrid1->Cells[2][f] == XDatos->TCategoriasCATEGORIA->Value)
                                {
                                        XDatos->QProductosCATEGORIA->Value=XDatos->TCategoriasCodCategoria->Value;
                                        {
                                        esta=true;
                                        }
                                }
                                XDatos->TCategorias->Next();
                        }
                        if (!esta)
                        {
                                XDatos->TCategorias->Append();
                                XDatos->TCategoriasCATEGORIA->Value = StringGrid1->Cells[2][f];
                                XDatos->TCategorias->Post();
                                XDatos->QProductosCATEGORIA->Value=XDatos->TCategoriasCodCategoria->Value;
                        }
                        bool esta2=false;
                        XDatos->TSubCat1->First();
                        // compruebo k la SubCategoria1 exista, si no es asi la añado
                        while(!XDatos->TSubCat1->Eof)
                        {
                                if (XDatos->TSubCat1CATEGORIA->Value == XDatos->QProductosCATEGORIA->Value && XDatos->TSubCat1SUBCAT1->Value == StringGrid1->Cells[3][f] && XDatos->TSubCat1->FieldByName("SUBCAT1") != "")
                                {
                                        XDatos->QProductosSUBCAT1->Value= XDatos->TSubCat1CodSUBCAT1->Value;
                                        esta2=true;
                                }
                                XDatos->TSubCat1->Next();
                        }
                        if (!esta2)
                        {
                                XDatos->TSubCat1->Append();
                                XDatos->TSubCat1SUBCAT1->Value = StringGrid1->Cells[3][f];
                                XDatos->TSubCat1CATEGORIA->Value = XDatos->QProductosCATEGORIA->Value;
                                XDatos->TSubCat1->Post();
                                XDatos->QProductosSUBCAT1->Value= XDatos->TSubCat1CodSUBCAT1->Value;
                        }
                        bool esta3=false;
                        XDatos->TSubCat2->First();
                        // compruebo k la SubCategoria2 exista, si no es asi la añado
                        while(!XDatos->TSubCat2->Eof)
                        {
                                if (XDatos->TSubCat2SUBCAT1->Value == XDatos->QProductosSUBCAT1->Value && XDatos->TSubCat2SUBCAT2->Value == StringGrid1->Cells[4][f] && XDatos->TSubCat2->FieldByName("SUBCAT2") != "")
                                {
                                        XDatos->QProductosSUBCAT2->Value = XDatos->TSubCat2CodSUBCAT2->Value;
                                        esta3=true;
                                }
                                XDatos->TSubCat2->Next();
                        }
                        if (!esta3)
                        {
                                XDatos->TSubCat2->Append();
                                XDatos->TSubCat2SUBCAT2->Value = StringGrid1->Cells[4][f];
                                XDatos->TSubCat2SUBCAT1->Value = XDatos->QProductosSUBCAT1->Value;
                                XDatos->TSubCat2->Post();
                                XDatos->QProductosSUBCAT2->Value = XDatos->TSubCat2CodSUBCAT2->Value;
                        }
                        bool esta4=false;
                        XDatos->TSubCat3->First();
                        // compruebo k la SubCategoria1 exista, si no es asi la añado
                        while(!XDatos->TSubCat3->Eof)
                        {
                                if (XDatos->TSubCat3SUBCAT2->Value == XDatos->QProductosSUBCAT2->Value && XDatos->TSubCat3SUBCAT3->Value == StringGrid1->Cells[5][f] && XDatos->TSubCat3->FieldByName("SUBCAT3") != "")
                                {
                                        XDatos->QProductosSUBCAT3->Value = XDatos->TSubCat3CodSUBCAT3->Value;
                                        esta4=true;
                                }
                                XDatos->TSubCat3->Next();
                        }
                        if (!esta4)
                        {
                                XDatos->TSubCat3->Append();
                                XDatos->TSubCat3SUBCAT3->Value = StringGrid1->Cells[5][f];
                                XDatos->TSubCat3SUBCAT2->Value = XDatos->QProductosSUBCAT2->Value;
                                XDatos->TSubCat3->Post();
                                XDatos->QProductosSUBCAT3->Value = XDatos->TSubCat3CodSUBCAT3->Value;

                        }
                        XDatos->QProductosPRODUCTO->Value = StringGrid1->Cells[6][f];
                        XDatos->QProductosKEY->Value = StringGrid1->Cells[7][f];

                        bool esta5=false;
                        XDatos->TMarcas->First();
                        // compruebo k la Marca exista, si no es asi la añado
                        while(!XDatos->TMarcas->Eof)
                        {
                                if (XDatos->TMarcasMARCA->Value == StringGrid1->Cells[8][f])
                                {
                                        XDatos->QProductosMARCA->Value = XDatos->TMarcasCodMARCA->Value;
                                        esta5=true;
                                }
                                XDatos->TMarcas->Next();
                        }
                        if (!esta5)
                        {
                                XDatos->TMarcas->Append();
                                XDatos->TMarcasMARCA->Value = StringGrid1->Cells[8][f];
                                XDatos->TMarcas->Post();
                                XDatos->QProductosMARCA->Value = XDatos->TMarcasCodMARCA->Value;
                        }
                        XDatos->QProductosDESCRIPCION->Value = StringGrid1->Cells[9][f];
                        XDatos->QProductosFOTOS->Value = StringGrid1->Cells[10][f];
                        XDatos->QProductosCATEGORIAX->Value = StringGrid1->Cells[11][f];
                        XDatos->QProductosCATEGORIAS->Value = StringGrid1->Cells[12][f];
                        //Confirmo el insert de productos 
                        XDatos->QProductos->Post();
                        // A partir de aqui los datos son de la tabla caracteristicas
                        for(int c=13;c<=StringGrid1->ColCount;c++)
                        {
                                if (StringGrid1->Cells[c][f]!="")
                                {
                                        if (c % 2 !=0)
                                        {
                                        XDatos->TCaracteristicas->Append();
                                        XDatos->TCaracteristicasCATEGORIA->Value = XDatos->QProductosCATEGORIA->Value;
                                        XDatos->TCaracteristicasSUBCAT1->Value = XDatos->QProductosSUBCAT1->Value;
                                        XDatos->TCaracteristicasSUBCAT2->Value = XDatos->QProductosSUBCAT2->Value;
                                        XDatos->TCaracteristicasSUBCAT3->Value = XDatos->QProductosSUBCAT3->Value;
                                        XDatos->TCaracteristicasref->Value = XDatos->QProductosREFERENCIA->Value;
                                        XDatos->TCaracteristicasCARACTERISTICA->Value = StringGrid1->Cells[c][f];
                                        XDatos->TCaracteristicasVALOR->Value = StringGrid1->Cells[c+1][f];
                                        // Confirmo la insercion de datos en caracteristicas
                                        XDatos->TCaracteristicas->Post();
                                        }
                                }
                        }
            //Cuento las veces que aparece un espacio sin datos en el StringGrid
            if (StringGrid1->Cells[0][f]=="")
                        cont ++;
            //Si aparecen mas de 100 espacios corto el proceso
            if (cont > 100)
                        break;
            }
        }
        XDatos->QRecorreProductos->Close();
        DBGrid1->Refresh();
}

He dejado comentarios en el codigo que indican lo que voy haciendo.

Soy bastante novato y provablemen te esto se podria hacer de alguna forma mas sencilla, no lo se, pero lo que me tarda es abusivo, gracias por contestar tan rapido :)

duilioisola 15-05-2012 14:26:46

Para saber si un registro existe o no, deberías preguntarlo directamente a la base y no recorrer cada registro y comparar.

Esta parte
Código:

//Recorro la tabla de productos con una Query para comprobar que el producto no este ya en la BD   
                while (!XDatos->QRecorreProductos->Eof)
                {
                        if (XDatos->QRecorreProductosREFERENCIA->Value == StringGrid1->Cells[0][f])
                                    existe = true;
                        XDatos->QRecorreProductos->Next();
                }

Deberías realizarla con un query que te responda si existe o no.
No conozco como hacerlo en C, pero sería algo así:
Código:

  // Ejecuto query que cuentas cuantos registros tienen referencia=[lo que busco]
  XQueryExisteDato->SQL->Text = 'SELECT COUNT(*) FROM DATOS WHERE REFERECIA='||StringGrid1->Cells[0][f];
  XQueryExisteDato->ExecSQL;

  // Si existe la cuenta será mayor a 0
  if (XQueryExisteDato->FieldByName('COUNT')->Value > 0)
  {existe = true;}

Lo mismo deberías hacer en cada caso en el que recorres las tablas con un while.

ErYcK 15-05-2012 14:34:51

Muchas gracias
 
Probare a hacerlo de esa forma, usando consultas a ver si se agiliza el proceso y os comento.
Gracias de nuevo por la ayuda :)

Neftali [Germán.Estévez] 16-05-2012 10:08:29

Creo que es un código perfecto para utilizar un profiler (aquí hay algunos). Con estos programas puedes saber exactamente qué parte de tu programa es la que está tardando más tiempo. Las lecturas, algún procedimiento con strings,...
Con eso podrás saber exactamente a qué parte tienes que atacar para optimizar.


La franja horaria es GMT +2. Ahora son las 10:29:11.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi