为什么当我使用字符串和数组时,linq搜索在效率上有很大的差异,尤其是对于大数据

本文关键字:于大 数据 尤其是 效率 字符串 搜索 linq 数组 为什么 | 更新日期: 2023-09-27 18:30:05

我想搜索包含关键字的学生的名字,起初我传递用逗号分隔的关键字,但我发现搜索时间太长。但是当我把这些关键字转换成一个数组时,它真的很快。为什么linq搜索在效率上存在巨大差异?这是因为数组还是linq?

使用字符串搜索

var keyWord="Lyly,Tom,Jack,Rose"; //and so on,more than 500 names
var student= Context.Students.Where(i => keyWord.Contains(i.Name));//very slow

使用数组搜索

var keyWord="Lyly,Tom,Jack,Rose"; //and so on,more than 500 names
 var keyWordArray=keyWord.split(',');
var student= Context.Students.Where(i => keyWordArray.Contains(i.Name));//fast

为什么当我使用字符串和数组时,linq搜索在效率上有很大的差异,尤其是对于大数据

是的,这是因为数组。Linq数据库提供商可以将带有数组的数据库转换为非常有效的形式

也就是说,在数据库终端中,

第一个查询将使用SQL Like,但第二个查询使用SQL IN。两者之间的差异很大。

为了满足一个学生的需求,SQL Like必须对整个字符串进行完全扫描。

SQL IN不必进行任何扫描,因为IN使用的是隐藏的集合。

请注意,这仅适用于数据库。如果您使用Linq2Object对上述比较进行基准测试,您可能看不到任何差异,可能是毫秒。

如果你想让Linq2Object也具有性能,你应该使用HashSet,就像这样:

var keyWord = "Lyly,Tom,Jack,Rose";
var keyWordSet = new HashSet<string>(keyWord.split(','));
var students = Context.Students
                .ToList()
                .Where(i => keyWordSet.Contains(i.Name));

主要差异是由于查询转换,其中String.Contains变成LIKEList.Contains变成IN(如@ChrisEelma所说)。

在LINQ to Objects中也会出现同样的差异,尽管每个差异的发生速度都比这里的(调用数据库)快。String.Contains()从开始到结束遍历整个字符串,然后返回是否找到了内容。相反,List.Contains()执行完全线性搜索,并在找到匹配项后返回。因此,List.Contains()最多将是相同的速度,但对于大多数元件,它将更快。

两者的MSDN链接:

String.Contains()

List.Contains()