Accélération des requêtes LINQ vers EF au maximum

J'ai une table de DB avec de grandes quantités de disques, je m'attends à ce qu'il monte jusqu'à 900 millions – 1 milliard de disques à un certain point.

Ce que j'essaie de comprendre, c'est comment accélérer mes requêtes LINQ to SQL qui ressemblent à ceci:

var allProducts = ctx.ProductsTransactions .Where(x => x.SearchedUserID == User.SearchedUserID) .ToList(); 

Où object ctx est mon object entité (classs mappées de ma database).

Certains users peuvent stocker jusqu'à 25 000 loggings, et la requête peut parfois prendre jusqu'à 10-15 secondes pour afficher les loggings.

Post-scriptum datatables que je récupère de DB devraient et sont en lecture seule, il ne peut être manipulé en aucune façon.

Est-il possible que je puisse accélérer cette requête?

Modifier:

Bon alors j'ai défini mon object entité dans mon controller comme ceci:

 public db_Entity ctx = new db_Entity(); 

Après avoir extrait datatables de la database, je les regroupe comme suit:

 var prepared = allProducts.ToList(); var filteredProducts = prepared.GroupBy(x => x.ItemID).Select(x => new ResultItem() { ID = x.Key, SaleNumber = x.Select(y => y.QuantityPurchased).Sum(), SaleEarning = x.Select(y => y.QuantityPurchased * y.SalePrice).Sum(), Title = x.Select(y => y.Title).FirstOrDefault(), CurrentPrice = x.OrderByDescending(y=>y.TransactionDate).Select(y=>y.SalePrice).FirstOrDefault(), GalleryURL = "http://somesite.com", SalePrice = x.Select(y => y.SalePrice).FirstOrDefault() }).ToList(); 

Après cela, j'ai placé le filterProducts dans un viewbag afin que je puisse le montrer à l'user final comme ceci:

 ViewBag.Products = filteredProducts; 

Avez-vous besoin de plus d'informations sur la structure de la table?

Edit # 2: Les gars, beaucoup d'entre vous ont mentionné que je devrais implémenter l'indexing sur UsedUserId dans ma table SQL … Comment puis-je faire cela?

Comme tout le monde l'a mentionné, la première chose qui vient à l'esprit est l'ajout d'un index à votre colonne de SearchedUserId dans SQL:

 CREATE NONCLUSTERED INDEX [idx_SearchedUserId] ON ProductsTransactions ([SearchedUserId] ASC|DESC) ON [filegroup_or_partition_name] 

Il existe d'autres options pour améliorer les performances, telles que le réglage fin des plates-forms de votre server, du matériel, etc. (l'utilisation du stockage flash améliore également les performances de manière significative).

Ne négligez pas l'optimization de cette partie de votre application, en n'utilisant PAS votre outil ORM.

Une command ADO.Net sera plus rapide et éliminera toute surcharge, soit avec une requête SQL, soit en passant des parameters à un proc stocké.

En outre, déterminez si vous pouvez mettre en cache des données dans votre application pour éliminer le besoin de l'access à la database.

Si vous souhaitez que cette requête particulière soit optimisée, vous voulez un index de couverture qui corresponde exactement à votre requête étendue, par exemple

 CREATE NONCLUSTERED INDEX [IX_ProductsTransactions_SearchedUserId_ItemId_etc] ON [ProductsTransactions] ( [SearchedUserId] ASC, [ItemId] ASC, [TransactionDate] DESC, [SalePrice] ASC, [Title] ASC ) 

Cela permettrait d' optimiser les performances de la requête définie, mais limiterait la possibilité de réutilisation des index pour d'autres requêtes.


Cependant, si datatables sont vraiment en lecture seule et ne peuvent jamais changer et puisque votre requête ne contient aucune variable, pourquoi ne pas calculer le résultat et returnner ces données directement à partir de votre couche d'application sans un appel à la database. Ce sera encore plus rapide.