【问题标题】:EF Core SQL Server Efficient Way To Handle Many WHERE CONTAINSEF Core SQL Server 处理许多 WHERE CONTAINS 的有效方法
【发布时间】:2022-01-30 18:10:18
【问题描述】:

我有一个不同数量的关键字/短语列表,我使用如下来创建 WHERE CONTAINS 查询。我试图排除包含关键字/短语之一的所有文章。

        if (itemQuery?.Keywords != null)
        {
            foreach (var keyword in itemQuery.Keywords)
            {
                var upperKeyword = keyword.Text.ToUpper();
                queryable = queryable.Where(x =>
                    !x.TitleUpper.Contains(upperKeyword));
            }
        }

但是,itemQuery?.Keywords 列表现在有 45 个关键字(可能更多),并且大大降低了 EF Core 查询的速度。返回数据需要 5 到 10 秒。如果我删除这部分查询,它会返回到 ms 以返回。

有关如何提高此查询的速度/效率的任何提示或想法。

更新 29/01

我将 TitleUpper 字段更新为全文,希望这会提高速度。以下是我尝试过的实现。

    var keywords = string.Join(\" OR \", itemQuery.Keywords.Select(x => $\"\\\"{x}\\\"\"));
    queryable = queryable.Where(f => !EF.Functions.Contains(f.TitleUpper, keywords));

传递的字符串将像这样格式化

\" 短语在这里\" OR \"单词\" OR \"某事\"

等等。所有 40 多个短语/单词。不幸的是,当我运行它时,它似乎比原始查询花费更长的时间!是否错误地执行了此操作?

    标签: sql-server entity-framework-core ef-code-first


    【解决方案1】:

    这个可能为您提供更好的 SQL 查询(我很确定逻辑与您正在做的事情相匹配):

    if (itemQuery?.Keywords != null)
    {
        queryable = queryable.Where(x => itemQuery.Keywords.Any(k => !x.TitleUpper.Contains(k.Text.ToUpper())));
    }
    

    但也许不是。问题是 Contains("something") 在 SQL 中转换为 LIKE '%something%'。这种类型的查询效率低下,因为无法使用该列上的索引(如果有的话)。它必须读取表中的每一行才能找到匹配项。所以你的桌子越大,需要的时间就越长。

    如果您能够将该查询更改为 StartsWith(),那么,如果您在该列上有索引,那么您的查询会快得多。

    如果您无法更改查询,则可以查看您正在使用的其他 Where 条件。尝试使用其他索引列来缩小结果集的范围,以限制Contains 需要处理的行数。

    您还可以查看在 SQL 中的该列上实现 Full-Text Search,这将提高该类型搜索的性能。我不知道Entity Framework 是否会自动使用全文搜索,但我知道there is support for it

    【讨论】:

    • LINQ 查询不可翻译为 SQL,但全文搜索是正确的建议。甚至是单独的搜索引擎。
    • @Gabriel Luci 感谢您的建议。不幸的是,这对我不起作用。我已经用我对全文所做的更改更新了这个问题,但它实际上更慢。任何建议指针将不胜感激。
    【解决方案2】:

    对于其他有类似问题的人。事实证明,EF Core 真的不喜欢 NVARCHAR(MAX) 字段!我将一个字段缩减为 NVARCHAR(500),它对查询的速度产生了巨大的影响。

    【讨论】:

      猜你喜欢
      • 2021-05-07
      • 1970-01-01
      • 2020-05-29
      • 1970-01-01
      • 2019-05-04
      • 1970-01-01
      • 2019-05-18
      • 2019-05-15
      • 1970-01-01
      相关资源
      最近更新 更多