2009-08-21 6 views
1

En général, l'un est-il plus rapide que l'autre, en supposant qu'un enregistrement est retourné?FirstOrDefault() || Sélectionnez() qui est le plus rapide?

Y a-t-il des avantages à utiliser l'un plutôt que l'autre?

À titre d'exemple:

DataContext.TableBlah.FirstOrDefault(_blah => _blah.id == 1); 

ou

var test = (from blah in TableBlah 
      where blah.id == 1 
      select blah) 
+3

Ne présumez rien, mesurez. –

+0

@Ed Bon point, je cherchais surtout s'il y avait un avantage à utiliser l'un sur l'autre. Par exemple, si FirstOrDefault a effectivement utilisé select sous le capot, etc ... –

Répondre

1

Je suis certain à 90% que

var test = dc.TableBlah.FirstOrDefault(_blah => _blah.id == 1); 

met en place l'arbre même expression exacte

var test = (from blah in dc.TableBlah 
      where blah.id == 1 
      select blah).FirstOrDefault(); 

Ainsi, votre deuxième exemple, il manque simplement l'avantage d'obtenir un seul enregistrement en appelant FirstOrDefault(). En termes de performance, ils seront identiques.

Personnellement, j'utiliserais plutôt SingleOrDefault(), puisque vous recherchez un seul article. SingleOrDefault() sera lancé si vous recevez plus d'un enregistrement.

2
var test = (from blah in TableBlah 
      where blah.id == 1 
      select blah) 

Cela peut revenir plus de 1 lignes, pour les enregistrements correspondants (contre FirstOrDefault).

Performance sage, je ne pense pas que ce devrait être différent.
Cela dépend aussi du nombre de lignes dans la table? La colonne Id est-elle indexée?

+0

Oui, la colonne Id est indexée ... –

+0

@Mike: Alors la différence devrait être la même que la course SELECT * FROM table WHERE ID = 1 vs SELECT TOP 1 * FROM TABLE WHERE ID = 1. S'il n'y a qu'un seul enregistrement correspondant à l'ID, les performances ne devraient pas poser de problème car la colonne est indexée. – shahkalpesh

2

FirstOrDefault retourne dès qu'il trouve un résultat, donc il peut être légèrement plus rapide, mais pas d'un ordre de grandeur ... Quoi qu'il en soit, votre deuxième requête peut retourner plus d'un résultat, donc ce n'est pas vraiment une comparaison équitable . Vous pouvez le comparer à SingleOrDefault à la place, ce qui est comme un Select, mais ne renvoie que 1 résultat. SingleOrDefault, comme un Select, doit parcourir la liste complète, mais il garantit que vous obtenez un et un seul résultat.

Remarque: Si vous utilisez LINQ to SQL, que vous deuxième requête peut être plus rapide, en fonction de vos index ...

1

Cela peut potentiellement être plus rapide.

var test = (from blah in TableBlah 
     where blah.id == 1 
     select blah) 

Cela dépend du fournisseur LINQ que vous utilisez. Si vous utilisez LINQ to Sql ou Subsonic, etc., ceci peut être traduit en un appel SQL direct, qui ne récupérera qu'une seule ligne de la base de données.

Dans LINQ to Objects, les deux instructions seront presque identiques, en raison du streaming de résultats LINQ.

+0

@Reed: Je pense que vous supposez que la table a seulement 1 ligne avec id = 1 quand vous avez dit "qui ne cherchera qu'une seule ligne de la DB". Est-ce correct? – shahkalpesh

+0

Oui. C'est avec cette hypothèse en place. LINQ to Sql et MS SQL server seront presque identiques, car cela optimisera l'autre option avec SELECT TOP, mais je crois que subsonic et d'autres fournisseurs linq ne le seront pas, donc ils vont sélectionner toutes les lignes, et streamer jusqu'à ce que en trouver un. Comme je l'ai dit, c'est une amélioration potentielle, mais cela dépend beaucoup de votre environnement. –

Questions connexes