我想知道是否有人可以帮助我。我有一个LINQ查询 - 没有问题,但返回数据需要太长时间
var result = Context.paf_wgs84.Where(c => c.Postcode.Contains(postcode)).Take(15);
很简单,用户输入的想法,使用AJAX,它返回一组15个可能的匹配。
问题是,有160万条记录
在management studio中运行以下代码大约需要3秒
SELECT code
FROM paf_wgs84
WHERE (code LIKE '%EC1%')
运行以下代码的时间不到一秒
SELECT TOP 15 code
FROM paf_wgs84
WHERE (code LIKE '%EC1%')
有没有办法在不使用.take()
的情况下在LINQ中执行类似操作?
答案 0 :(得分:2)
你可以尝试这样的事情。这只会返回一列。
var result = Context.paf_wgs84.Where(c => c.Postcode.Contains(postcode)).Select(x=>new {x.Postcode}).Take(15);
生成的Sql语句将如下所示。
/*
-- Region Parameters
DECLARE @p0 VarChar(1000) = '%s%'
-- EndRegion
SELECT TOP (15) [t0].[code]
FROM [paf_wgs84] AS [t0]
WHERE [t0].[code] LIKE @p0
*/
答案 1 :(得分:1)
问题可能是你在statemnt中的contains方法没有被映射到sql中的like语句而你最终将所有行都放到sql中然后在你的web层中进行cotains搜索而不是做同样的事情在你的数据库中。
使用SqlMethods来实现相同的... somethig如下:
SqlMethods.Like(c.Postcode, string.Format("%{0}%",postcode));
有时你也可以使用字符串方法,如:String.StartsWith或String.Ends,但在此你不能...
另外 - 启动%的LIKE子句很少是一个好主意 - 尤其是它无法有效地使用任何索引。使用“全文搜索”可能会有更好的表现;但这不能直接通过LINQ
获得希望能帮到你解决问题。
答案 2 :(得分:0)
我将声明改为
var result = Context.paf_wgs84.Where(c => c.Postcode.StartsWith(postcode)).Take(10).Select(c => c.Postcode).ToArray();
我使用foreach外观添加到字符串数组 - 我认为这是我失去时间的地方!
感谢大家的帮助。
答案 3 :(得分:0)
使用新的FETCH和OFFSET语句在SQL Server 2012中大大提高了这些类型查询的性能(尽管到目前为止我还没有看到太多的基准测试数据......)。
问题是EF还没有利用这些新功能。
一种可能的解决方案是使用SQL Server 2012并使用FETCH / OFFSET编写一个sproc,然后使用EF进行目标。绝对不是短期解决方案,但我想指出这个选项。