C# 将LINQ加速到 ;EF查询到max

C# 将LINQ加速到 ;EF查询到max,c#,asp.net,sql-server,asp.net-mvc,linq,C#,Asp.net,Sql Server,Asp.net Mvc,Linq,我有一个包含大量记录的DB表,我预计它在某一点上会增加到9亿到10亿条记录 我想弄清楚的是如何加速我的LINQ到SQL查询,目前看起来是这样的: var allProducts = ctx.ProductsTransactions .Where(x => x.SearchedUserID == User.SearchedUserID) .ToList(); public db_Entity ctx = n

我有一个包含大量记录的DB表,我预计它在某一点上会增加到9亿到10亿条记录

我想弄清楚的是如何加速我的LINQ到SQL查询,目前看起来是这样的:

var allProducts = ctx.ProductsTransactions
                     .Where(x => x.SearchedUserID == User.SearchedUserID)
                     .ToList();
public db_Entity ctx = new db_Entity();
ViewBag.Products = filteredProducts;
其中ctx对象是我的实体对象(数据库的映射类)

有些用户最多可以存储25000条记录,查询有时需要10-15秒才能显示这些记录

另外,我从数据库中检索的数据应该是只读的,不能以任何方式进行操作

我有没有办法加快这个查询的速度

编辑:

我在控制器中定义了实体对象,如下所示:

var allProducts = ctx.ProductsTransactions
                     .Where(x => x.SearchedUserID == User.SearchedUserID)
                     .ToList();
public db_Entity ctx = new db_Entity();
ViewBag.Products = filteredProducts;
从数据库中取出数据后,我将其分组如下:

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();
之后,我将filteredProducts放入一个viewbag中,以便向最终用户显示它,如下所示:

var allProducts = ctx.ProductsTransactions
                     .Where(x => x.SearchedUserID == User.SearchedUserID)
                     .ToList();
public db_Entity ctx = new db_Entity();
ViewBag.Products = filteredProducts;
你们需要更多关于桌子结构的信息吗


编辑#2:各位,你们很多人都提到我应该在SQL表中的SearchedUserId上实现索引。。。我该怎么做呢?

几乎每个人都提到过,首先想到的是在SQL中为您的
SearchedUserId
列添加一个索引:

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

还有一些其他选项可以提高性能,例如微调服务器平台、硬件等(使用闪存也将显著提高性能)。

正如几乎所有人都提到的,首先想到的是在SQL中为您的
SearchedUserId
列添加索引:

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

还有一些其他选项可以提高性能,例如微调服务器平台、硬件等(使用闪存也将显著提高性能)。

如果您希望优化此特定查询,则需要与扩展查询完全匹配的覆盖索引,例如

CREATE NONCLUSTERED INDEX [IX_ProductsTransactions_SearchedUserId_ItemId_etc]
    ON [ProductsTransactions]
    (
        [SearchedUserId] ASC,
        [ItemId] ASC,
        [TransactionDate] DESC,
        [SalePrice] ASC,
        [Title] ASC
    )
这将最大化已定义查询的性能,但会限制索引对其他查询的可重用性



但是,如果数据是真正的只读数据,并且永远不会更改,并且由于查询不包含任何变量,为什么不预先计算结果并直接从应用程序层返回数据,而不调用数据库呢。这将更快。

如果您希望优化此特定查询,那么您需要一个与扩展查询完全匹配的覆盖索引,例如

CREATE NONCLUSTERED INDEX [IX_ProductsTransactions_SearchedUserId_ItemId_etc]
    ON [ProductsTransactions]
    (
        [SearchedUserId] ASC,
        [ItemId] ASC,
        [TransactionDate] DESC,
        [SalePrice] ASC,
        [Title] ASC
    )
这将最大化已定义查询的性能,但会限制索引对其他查询的可重用性



但是,如果数据是真正的只读数据,并且永远不会更改,并且由于查询不包含任何变量,为什么不预先计算结果并直接从应用程序层返回数据,而不调用数据库呢。这会更快。

不要忽略优化应用程序的这一部分,不要使用ORM工具

ADO.Net命令将更快,并消除任何开销,无论是SQL查询,还是将参数传递给存储的进程


同时,考虑是否可以缓存应用程序中的数据以消除数据库命中的需要。

< P>不要忽略应用ORM工具来优化应用程序的这一部分。

ADO.Net命令将更快,并消除任何开销,无论是SQL查询,还是将参数传递给存储的进程


也可以考虑是否可以缓存应用程序中的数据,以消除数据库命中的需要。

有一百万种方法可以加快速度,但我们需要更多地了解您的数据库/代码/数据/服务器等。我们现在真正能做的就是确保您在
SearchedUserID
列上有一个索引。我想暗示的是,这个网站不是一个提出此类问题的好地方。我们需要非常具体的编程问题,性能问题通常非常通用。@User987您使用的是LINQ到SQL还是LINQ到EF?如果LINQtoSQL无法将您编写的内容转换为SQL,它将加载内存中的所有内容。不要用它。另外,简化查询。LINQ不是SQL的替代品。如果查询在SQL或LINQ中看起来很难看,那么它的性能将非常差。您必须检查生成的SQL语句以查看实际执行的是什么,您应该考虑在服务器上实现分页,这样您就不必在页面加载时加载25K行,每次加载10, 20行或50行。还可以替换此代码< x>选择(y= > y.QuyTyBuy)。(y=>y.QuantityPurchased)有无数种方法可以加快这一速度,但我们需要更多地了解您的数据库/代码/数据/服务器等。我们现在真正能做的就是确保您在
SearchedUserID
列上有一个索引。我想暗示的是,这个网站不是一个提出此类问题的好地方。我们需要ire非常具体的编程问题和性能问题通常非常通用。@User987您使用的是LINQ to SQL还是LINQ to EF?如果LINQ to SQL无法将您编写的内容转换为SQL,它将加载内存中的所有内容。不要使用它。另外,简化查询。LINQ不是SQL的替代品。如果查询在SQL或LINQ中看起来很难看,它将执行非常复杂的操作很糟糕。你必须检查生成的SQL语句以查看实际执行的是什么,你应该考虑在服务器上实现分页,这样你就不必在页面加载时加载25K行,每次加载10, 20行或50行。也可以用这个代码< x.SUM替换这个<代码> x.Sead(y= > y.QuyTyBuy).SUM()/<代码>。(y=>y.QuantityPurchased)mazing,ty用于此!:)我应该将什么作为文件组或分区名称?分区名称如“C驱动器”中所示,或者?当您创建SQL数据库时,您定义了一个文件组或分区名称(或者可以保留为默认名称)。您必须检查数据库属性以找到它是什么。mazing,ty用于此!:)我应该把什么作为文件组或分区名?帕尔蒂