加快LINQ查询的技巧?

时间:2011-09-29 10:51:20

标签: .net linq

我有一个LINQ查询,它搜索大约250,000条记录的SQL表,只搜索2个字段。这两个字段都已被编入索引,但我发现它仍然运行得相当缓慢。

以下是代码,任何人都可以提出任何建议以加快速度吗?

感谢

var qryN = (
    from bn in dbs.Uploads
    orderby bn.ID descending
    select new
    {

        ID = bn.ID,
        Serial = bn.serial_no,
        Manufacturer = bn.Mfgr,
        Model = bn.model,
        Code = bn.code,
        Qty = bn.qty,
        Description = bn.description,
        Comments = bn.comments,
        Location = bn.location,
        Price = bn.price,
        Email = "Register / Login for full details"
    });

if (dlType.Text != " " && dlType.Text != "")
{
    qryN = qryN.Where(bn => bn.Manufacturer == dlType.SelectedValue);
}

if (txtWord.Text != "")
{
    qryN = qryN.Where(bn => bn.Description.Contains(txtWord.Text));
    }

gvLoggedOff.DataSource =
    from p in qryN
    select new
    {
        p.ID, 
        p.Serial, 
        p.Manufacturer, 
        p.Model, p.Code, 
        p.Qty, 
        p.Description, 
        p.Comments, 
        p.Location, 
        p.Price, 
        p.Email
    };

gvLoggedOff.DataBind();    var qryN = (
    from bn in dbs.Uploads
    orderby bn.ID descending
    select new
    {

        ID = bn.ID,
        Serial = bn.serial_no,
        Manufacturer = bn.Mfgr,
        Model = bn.model,
        Code = bn.code,
        Qty = bn.qty,
        Description = bn.description,
        Comments = bn.comments,
        Location = bn.location,
        Price = bn.price,
        Email = "Register / Login for full details"
    });

if (dlType.Text != " " && dlType.Text != "")
{
    qryN = qryN.Where(bn => bn.Manufacturer == dlType.SelectedValue);
}

if (txtWord.Text != "")
{
    qryN = qryN.Where(bn => bn.Description.Contains(txtWord.Text));
    }

gvLoggedOff.DataSource =
    from p in qryN
    select new
    {
        p.ID, 
        p.Serial, 
        p.Manufacturer, 
        p.Model, p.Code, 
        p.Qty, 
        p.Description, 
        p.Comments, 
        p.Location, 
        p.Price, 
        p.Email
    };

gvLoggedOff.DataBind();

3 个答案:

答案 0 :(得分:7)

Description上的过滤器可能有问题:

qryN = qryN.Where(bn => bn.Description.Contains(txtWord.Text));

Contains次调用会转换为SQL description LIKE '%' + @p0 + '%'。这意味着即使您在description列上有索引,SQL服务器也必须遍历整个索引(或者甚至是整个表)。如果可能,请将该行更改为以下内容:

qryN = qryN.Where(bn => bn.Description.StartsWith(txtWord.Text));

这将转换为description LIKE @p0 + '%',这允许您的数据库服务器有效地使用索引。

答案 1 :(得分:1)

两件事:

  • 由于您要添加过滤器,请将投影(选择新的匿名类型)移至最后一行而不是第一行DataSource行。
  • 你很早就订购了。除非可查询或查询分析器足够智能以分析和优化它,否则数据库在开始过滤之前必须订购250,000行。尽可能晚地移动排序,可能就在投影发生之前。

以下是修改样本的简短尝试:

var qryN = dbs.Uploads.AsQueryable();

if (dlType.Text != " " && dlType.Text != "")
    qryN = qryN.Where(bn => bn.Mfgr == dlType.SelectedValue);

if (txtWord.Text != "")
    qryN = qryN.Where(bn => bn.description.Contains(txtWord.Text));

gvLoggedOff.DataSource = qryN.OrderByDescending(bn => bn.ID)
    .Select(bn => new { 
        bn.ID, Serial = bn.serial_no, Manufacturer = bn.Mfgr,
        Model = bn.model, Code = bn.code, Qty = bn.qty,
        Description = bn.description, Comments = bn.comments,
        Location = bn.location, Price = bn.price,
        Email = "Register / Login for full details" });

gvLoggedOff.DataBind();

由于这被接受为答案:Steven's answer关于文本搜索可能也适用于某些情况。全文搜索会消耗你不相信的表现。

答案 2 :(得分:1)

Description.Contains听起来很重,您可以尝试使用全文搜索。

Here是一篇描述如何使用LINQ中的FTS的帖子。