Partage
  • Partager sur Facebook
  • Partager sur Twitter

[ASP.NET] Boucle trop longue

    10 mai 2011 à 20:19:50

    Bonjour,
    Sur une page web j'ai un champs "Contact" qui permet à l'utilisateur de chercher une personne par son numéro de matricule.
    J'ai fait une boucle qui parcourt ligne par ligne toute ma table des personnes et elle ne s'arrête pas tant que ce qui a dans le champs "contact" n'est pas égal à une ligne dans la colonne PersonneNo.
    Lorsque le numéro de personne recherché est proche de 1 il n'y a pas de problème, cependant plus le numéro de personne recherché est grand plus le programme met de temps. J'ai plusieurs centaines de milliers de personnes dans ma base de données et au delà du numéro 100 le programme commence à mettre énormément de temps, alors je ne vous parle même pas de ce que ça donne si le numéro est très grand ou bien si pas égal à une valeur de la bdd, j'ai pas attendu assez longtemps pour savoir combien de temps ça pouvait mettre!

    En gros ma question c'est comment améliorer les performances de cette recherche et faire en sorte que peu importe le numéro recherché, le résultat soit vite trouvé?

    Voici mon code:
    String requeteSQL = "SELECT MAX(personne_no) FROM UA1_PERSONNE";
                    SqlCommand oCommand = new SqlCommand(requeteSQL, oConnection2);
                    int max = (int)oCommand.ExecuteScalar();
                    int i = 0;
                    while (i < max+1)
                    {
                        IPersonne pers = personne.Lire(i);
                        if (pers != null)
                        {
                            if (Contact.Text.Equals(Convert.ToString(pers.PersonneNo)))
                            {
                                Response.Redirect("Contacts.aspx?PersonneNo=" + i);
                            }
                            else
                            {
                                i++;
                            }
                        }
                        else
                        {
                            i++;
                        }
                    }
                    LabelErreur.Text = "Ce numéro de personne n'existe pas";
    


    Merci d'avance
    • Partager sur Facebook
    • Partager sur Twitter
      10 mai 2011 à 21:27:35

      o_O Est-ce que tu comprends ce que tu fais ? :o

      Tu as un numéro de personne qui a été donné par l'utilisateur (Contact.Text): on va l'appeler numeroATrouver. Tu veux savoir si un record correspondant à ce numéro existe dans ta base de données.

      ... Et pour faire ça, pour chaque numéro i, tu prends la personne portant la numéro i... et tu regardes si elle porte le numéro numeroATrouver. Gné ? o_O Ca te semble vraiment utile de parcourir tous les records dans l'autre, numéro par numéro, jusqu'à tomber sur celle qui porte le numéro qui t'intéresse ? Autant prendre immédiatement celle qui porte ce numéro-là !

      Parcourir tous les records un par un jusqu'à tomber sur le bon c'est de la folie pure, surtout si une simple clause WHERE dans une requête SQL pourrait suffire, et en particulier si le nombre de records est élevé ! :waw:
      En plus le code que tu dois écrire ici est pourtant simple :
      int numeroATrouver = Convert.ToInt32(Contact.Text);
      IPersonne pers = personne.Lire(numeroATrouver); // on charge la personne avec le numéro demandé
      
      if (pers != null) // si elle existe
      {
          Response.Redirect("Contacts.aspx?PersonneNo=" + i);
      }
      else // sinon
      {
          LabelErreur.Text = "Ce numéro de personne n'existe pas";
      }
      


      Note qu'on pourrait encore accélérer, car ici tout ce qui t'intéresse c'est savoir si le numéro est présent dans la table donc il n'y a pas besoin de charger tout l'objet personne correspondant.
      Il suffirait d'écrire une nouvelle méthode Exists dans la classe personne qui se charge de faire ça avec une requête appropriée.

      Note également que cette classe personne est apparemment prévue pour encapsuler l'accès au contenu de la table UA1_PERSONNE, donc en lançant toi-même une requête SQL tu fais le boulot à sa place et tu passes complètement à côté de sa raison d'être. En dehors du code de cette classe, tu ne devrais jamais envoyer de commandes SQL qui portent uniquement sur la table UA1_PERSONNE (puisque c'est le travail de cette classe et de personne d'autre).
      .
      • Partager sur Facebook
      • Partager sur Twitter
        11 mai 2011 à 15:16:38

        La solution la plus simple ne serait pas de rajouter un WHERE?

        SELECT personne_no 
        FROM AU1_PERSONNE
        WHERE personne_no=(le contact que tu veux trouver)
        
        • Partager sur Facebook
        • Partager sur Twitter
          11 mai 2011 à 15:21:01

          Si, mais ça c'est ce que fait déjà sa méthode personne.Lire(), donc autant l'utiliser.

          D'autant que comme je l'ai dit, sa classe personne est apparemment conçue pour encapsuler la table AU1_PERSONNE, donc effectuer une requête sur cette table depuis une autre classe est une très mauvaise idée.
          • Partager sur Facebook
          • Partager sur Twitter

          [ASP.NET] Boucle trop longue

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown