【发布时间】:2011-11-01 17:47:50
【问题描述】:
我在 Windows Phone 7 上遇到了 Linq to SQL 性能问题,但我真的不确定我做错了什么(我几乎没有使用 Linq to SQL 的经验,而且我阅读的越多,我越来越困惑了叹气)。
背景
我有一个本地 SQL CE 数据库,其中包含五个表,每个表中有两列(int 主键和nvarchar 值,加上索引),每个表中大约有 100,000 个条目。数据库大小约为 20MB,按照 Microsoft 自己的 MVVM 本地数据库示例中的指南实施。
问题
尽可能简化后,我的视图模型中有一个查询,如下所示:
var query =
(
from t1 in db.table1
join t2 in db.table2 on t1.id equals t2.id
join t3 in db.table3 on t1.id equals t3.id
join t4 in db.table4 on t1.id equals t4.id
join t5 in db.table5 on t1.id equals t5.id
where
SqlMethods.Like(t5.value, "%"+searchTerm+"%")
select new Results
{
Field1 = t1.value,
Field2 = t2.value,
Field3 = t3.value,
Field4 = t4.value,
Field5 = t5.value,
}
).Take(100);
SearchResults = new ObservableCollection<Results>(query);
此产品产生以下 SQL:
SELECT TOP (100)
[t0].[value] AS [Field1],
[t1].[value] AS [Field2],
[t2].[value] AS [Field3],
[t3].[value] AS [Field4],
[t4].[value] AS [Field5]
FROM
[table1] AS [t0],
[table2] AS [t1],
[table3] AS [t2],
[table4] AS [t3],
[table5] AS [t4]
WHERE ([t4].[value] LIKE @p0)
AND ([t0].[id] = [t4].[id])
AND ([t0].[id] = [t3].[id])
AND ([t0].[id] = [t2].[id])
AND ([t0].[id] = [t1].[id])
问题是,当搜索词非常具体(只有一个结果)时,平均执行时间约为 5 秒。这是在我添加任何其他要求之前,例如多个 where 子句、排名、排序等。即使我搜索我知道的数据库中的第一行,它仍然需要大约 5 秒。
如果我改变方法并搜索一些非常常见的内容(例如“the”),则只需大约 100 毫秒 即可执行。我知道带有通配符的Like 比直接比较== 更复杂,但我不知道为什么性能如此不同。
(我知道这是无用的比较,因为它们是苹果和橘子,但我之前在用 MySQL 编写的同一个数据库上执行了类似的查询,无论我搜索什么,它们始终在大约 0.3-0.4 秒内得到结果)。
我是否遗漏了一些非常明显的东西?我已经按照 Microsoft 的示例并在线阅读了许多教程,但我找不到这个查询如此缓慢的原因。非常感谢您提供的任何建议。
【问题讨论】:
-
我强烈建议您尝试不使用使用 LINQ 执行相同的查询。我怀疑您会看到相同的性能,这意味着根本不应该归咎于 LINQ。请记住,通过这样的通配符搜索,数据库基本上不能使用任何索引 - 而通过直接相等匹配,它应该能够非常快速地找到正确的条目。
-
感谢乔恩的快速回复。你是对的,我刚刚使用生成的 SQL 在我的桌面上分析了同一个数据库,并获得了相似的性能比(特定查询为 1.2 秒,通用查询为 0.02 秒)。我没有意识到通配符会对性能产生如此大的影响。
标签: c# sql linq-to-sql windows-phone-7