2010-02-03 7 views
1

Je suis en train de tester les performances de Linq maintenant et je n'arrive pas à comprendre ce qui a été gaspillé pendant un certain temps (MS-SQL Server 2005).performance linq: linq vs t-sql - où le temps passe-t-il?

Voici donc ce que j'ai: table unique avec des index clusterisés et non-cluster, toutes les recherches sont effectuées à l'aide de colonnes qui sont couvertes à 100% par un index non-cluster. J'ai 10 000 enregistrements, et toutes les opérations "touchent" tous les enregistrements un par un. Et maintenant les temps:

T-SQL:

  • vérifier si chaque enregistrement existe (SI EXISTE ...); oui, elle existe - 0:30 (30 secondes)
  • mise à jour chaque enregistrement - 1:16

LINQ:

  • aller chercher des enregistrements uniques (SingleOrDefault) - 5: 58
  • mise à jour chaque enregistrement (il contient la partie extraction) - 9:34

Ok, la vérification de l'existence est pas réellement équivalent l INQ et T-SQL, mais ce qui me dérange vraiment est le fait:

LINQ(fetch)+TSQL(update) < LINQ(update) 

Notez également que la partie réelle de mise à jour est plus rapide que la récupération seule!

La mise à jour dans LINQ est déjà optimisée pour utiliser l'index primaire (en cluster) et non la table entière (clause WHERE).

Alors, où est passé 2 minutes?

EDIT

Lorsque vous répondez s'il vous plaît répondre à la question de savoir pourquoi est telle différence entre LINQ et TSQL. S'il vous plaît ne pas discuter sujet comme: TSQL est pour les ensembles, vous devriez le faire dans un lot (tous les enregistrements en une fois), vous devez rendre TSQL plus rapide. Je vous remercie.

Edit2:

La structure de la table est assez facile: id (PK), nom (int, index externe), champ bit + 40 champs ou quelque chose comme ça

Pour concentrer sur requête spécifique, je lance cette boucle:

declare @i int; 
declare @nr int; 
declare @p1 bit; 
declare @p0 int; 

set @i = 0; 
set @nr = 1000000000; 

while @i<10000 
begin 
    select @p0=id,@p1=bit_field from test_mono where [email protected]; 
    set @p1 = 1- @p1; 
    update test_mono set [email protected] where [email protected]; 
    set @i = @i+1; 
    set @nr = @nr-1; 
end 

Un petit commentaire à ce: bit_field ici me sert l'assurance que quelque chose sera modificateur à coup sûr. Les compteurs qui montent et descendent proviennent de données réelles, je devais m'assurer avec chaque sélection que je recevais un enregistrement. Et le dernier - avec LINQ la seule différence est SELECT, je vais chercher tous les champs (UPDATE est copié & collé). Cependant, je peux prendre le temps de LINQ SELECT et l'ajouter à ce moment (de TSQL) et je devrais obtenir LINQ SELECT + UPDATE. Mais je n'ai pas ce temps.

Avec l'édition précédente, j'ai décrit une structure un peu différente, la raison en est que j'essaie de rendre ceci aussi clair que possible.Je n'aime pas moi-même les exemples de cas réels sérieux, donc je vais essayer de rendre les choses faciles pour les lecteurs ;-)

+0

Avez-vous regardé le SQL généré par LINQ (en utilisant DataContext.Log) et avez ensuite essayé d'exécuter l'analyseur de requêtes sur cela? –

+0

Je suppose par Linq que vous voulez vraiment dire Linq to SQL? –

+0

surcharge, LINQ doit accéder à la base de données en utilisant les mêmes commandes SQL que vous pouvez exécuter en mode autonome. ajouter une fraction de seconde à 10.000 opérations, et il ajoute –

Répondre

1

Vous pouvez commencer par utiliser un outil tel que LINQPad pour voir quelles sont les requêtes SQL réelles exécuté par LINQ.

Personnellement cependant, j'ai vu cela maintes et maintes fois, donc j'ai tendance quand la performance est la première priorité que je reste avec TSQL.

Plus que probablement le SQL généré a quelques bizarreries. Nous aurions besoin de plus d'informations sur la nature de vos requêtes pour avoir une idée de ce que vous pourriez travailler.

+0

Merci pour le lien, j'ai essayé, mais je ne vois rien de spécial à ce sujet. Je peux vider LINQ-> SQL par moi-même, il ne montre pas le plan d'exécution sql, donc ses capacités sont plutôt limitées (comparé au code LINQ + log). – greenoldman