2

J'ai cette requêteComment optimiser cette Nhibernate requête (835ms)

var temp = from x in ActiveRecordLinq.AsQueryable<Circuits>() 
         where x.User_Created == false 
         orderby x.Description 
         select x; 

De NHibernate Profiler
Durée de la requête
-Database seulement: 7ms
-Total: 835ms

La requête générée :

SELECT this_.Circuit_ID  as Circuit1_35_0_, 
    this_.[Description] as column2_35_0_, 
     this_.[User_Created] as column3_35_0_ 
FROM  dbo.Circuit this_ 
WHERE this_.[User_Created] = 0 /* @p0 */ 
ORDER BY this_.[Description] asc 

Cela semble être une jolie requête simple. Il renvoie 6821 lignes. Tout ce que j'utilise pour cela est de remplir une liste déroulante.

Merci à l'avance

+2

Il n'y a rien que vous pouvez optimiser là-bas. Récupérer près de 7k lignes et les afficher dans une liste déroulante est juste un mauvais design. –

+0

La seule chose que vous pouvez optimiser est le nombre d'éléments dans cette liste déroulante :). Pouvez-vous faire quelque chose comme une saisie semi-automatique? – sirrocco

+0

@Diego, je suis juste en train de mettre à jour le design actuel (en passant de sql). L'utilisateur doit être en mesure de sélectionner un circuit et il se trouve maintenant 7k d'entre eux maintenant. Comment iriez-vous en mettant en œuvre ceci? – Gage

Répondre

2

Ok, si vous insistez sur le 7k (0 VRAIMENT pensez que vous devriez arrêter de repenser votre conception ... mais ...), vous pouvez essayer de faire une requête HQL pour simplement sélectionner les champs dont vous avez besoin de l'objet, au lieu d'interroger pour les objets eux-mêmes. Avec la requête que vous avez écrite, nHibernate charge les données de la base de données qui se produit assez rapidement comme vous l'avez noté. Mais ALORS, basé sur la requête Linq que vous avez écrite, il initialise, remplit et retourne les objets 7k Circuit. ce qui prend probablement un certain temps ...

Et puisque vous n'utilisez pas réellement l '"objet" de manière significative dans ce cas (juste une paire de texte et de valeur pour la liste déroulante) vous n'avez vraiment pas besoin nHibernate pour construire les objets. Essayez de changer votre code pour retourner la paire texte/valeur avec HQL ou LinqToNHibernate.

le HQL ressemblerait à quelque chose comme ceci:

select c.description, c.id from Circuit c 
where c.ordercreated = false 
orderby c.description 

Je sais que vous pouvez le faire avec LinqToNhibernate aussi bien, je n'ai pas des exemples rapides à portée de main.

+0

C'est ce que j'ai fini par essayer. Quand j'ai sélectionné x.Description au lieu de x, il a réduit le temps de moitié. Puisque cela ne se produit qu'au démarrage, je vais le laisser car une fois que l'utilisateur ouvre le programme, ils ont tendance à le laisser ouvert – Gage

1

Attendez ... vous mettez près 7k éléments dans une liste déroulante? Est-ce que je comprends bien?

Si oui, serait-il possible d'utiliser des listes déroulantes dépendantes avec ajax ou un design similaire?

Si cela est sur le web, vous êtes à la recherche probablement à une page relativement importante qui doit être transmis vers un ordinateur client, afin d'optimiser la requête NH peut être une optimisation prématurée ...

+0

Oui 7k articles à une liste déroulante lol. C'est une application C# exécutée à partir d'un partage réseau. – Gage

1

7k entrées dans une liste déroulante est mauvaise pour l'expérience utilisateur. Puisque vous commandez déjà par description je suppose que vos utilisateurs savent déjà (au moins partiellement) ce qu'ils veulent sélectionner. Donc, donner une liste complète entrave réellement l'utilisateur.

Puisque vous demandent quel est autocomplétion

imaginer un champ d'entrée où les types d'utilisateurs un certain nombre de caractères. Lorsque l'utilisateur tape ce qu'il veut, la requête se déclenche. Ce paramètre de chaîne sera utilisé pour limiter davantage la taille de l'ensemble de résultats.

donc l'implémentation de requête est quelque chose comme ceci pseudocode:

//passedParameter => "%foo%" 
var temp = from x in ActiveRecordLinq.AsQueryable<Circuits>() 
       where x.User_Created == false 
       and x.Description like passedParameter 
       orderby x.Description 
       select x; 

La mise en œuvre effective à la fois la requête ainsi que si vous décidez de mettre en œuvre « %% foo » ou « foo% » etc, il est votre décision .

L'expérience utilisateur sera réduite à l'écriture 'foo' dans le champ de saisie et les résultats ne chercheront que le Circuits pertinent sur lequel l'utilisateur va sélectionner ce qu'il veut. Si l'ensemble de résultats est encore trop grand, l'utilisateur peut ajouter 'b' au 'foo' déjà tapé en faisant un 'foob', là encore la requête se déclenche à nouveau en retournant un ensemble de résultats encore plus limité.

Lorsque vous tapez dans google et il vous donne des suggestions sur la mise en œuvre de son vol une autocomplétion

+0

C'est ce que j'ai pensé, le seul problème est que l'utilisateur doit pouvoir taper dedans propre nom de circuit aussi (une des raisons pour lesquelles la liste est si grande). Oui, je l'aurais conçu différemment, mais ça dépasse largement ce point. – Gage