【问题标题】:Is there any way to optimize this LINQ where clause that searches for multiple keywords on multiple columns?有没有办法优化这个在多列上搜索多个关键字的 LINQ where 子句?
【发布时间】:2010-05-22 10:56:54
【问题描述】:

我有一个 LINQ 查询,可以在多个列上搜索多个关键字。目的是用户可以搜索多个关键字,它将在我的Media 实体中的每个属性上搜索关键字。这是一个简化的例子:

var result = repository.GetAll<Media>().Where(x =>
    x.Title.Contains("Apples") || x.Description.Contains("Apples") || x.Tags.Contains("Apples") ||
    x.Title.Contains("Oranges") || x.Description.Contains("Oranges") || x.Tags.Contains("Oranges") ||
    x.Title.Contains("Pears") || x.Description.Contains("Pears") || x.Tags.Contains("Pears")
);

换句话说,我想在TitleDescriptionTags 列上搜索关键字ApplesOrangesPears

输出的 SQL 如下所示:

SELECT *
FROM Media this_
WHERE  ((((((((
       this_.Title like '%Apples%'
    or this_.Description like '%Apples%')
    or this_.Tags like '%Apples%')

    or this_.Title like '%Oranges%')
    or this_.Description like '%Oranges%')
    or this_.Tags like '%Oranges%')

    or this_.Title like '%Pears%')
    or this_.Description like '%Pears%')
    or this_.Tags like '%Pears%')

在这种情况下,这是最优化的 SQL 吗?如果不是,我如何重写 LINQ 查询以创建最佳 SQL 语句?我使用 SQLite 进行测试,使用 SQL Server 进行实际部署。

【问题讨论】:

    标签: c# sql linq nhibernate


    【解决方案1】:

    真正的性能损失是这种查询很难优化。您想查找默认情况下不可索引的子字符串。

    从纯粹的 L2S 角度来看,您无能为力。但是,如果您可以启用全文搜索,您将拥有更好的工具来加快查询速度。

    See this Stack Overflow post for more info.

    【讨论】:

    • 感谢您的回答。我像 Jon Skeet 提到的那样运行了一个测试,结果表明我预期的记录数的执行时间可以忽略不计。
    【解决方案2】:

    说实话,我看不出它怎么能明显更快。诚然,“包含”风格的通配符在开始时可能相当慢(例如,与“开始于”相比)。

    您看过 SQL Server 执行计划是什么样的吗?使用真实的数据集,实际性能如何?

    【讨论】:

    • 我刚刚在 SQLite 数据库中创建了 2000 条记录,并运行了一个与我发布的查询非常相似的查询。根据 NProf 的说法,整个查询只用了 43 毫秒。实际上,客户端只有几千条记录(不是几百万条),所以性能非常好。
    • @Daniel T:你也应该在 SQL Server 上尝试一下——尽管只有数千条记录,我不认为这是个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 2013-01-01
    • 1970-01-01
    • 2010-10-10
    • 1970-01-01
    相关资源
    最近更新 更多