非常慢的Linq到SQL在WP7上选择性能

问题描述:

我在Linq上遇到了Windows Phone 7上的SQL性能问题,但我真的不知道我在做什么错了(我几乎没有Linq的经验SQL,而我读得越多,我越感到困惑感叹)。非常慢的Linq到SQL在WP7上选择性能

背景

我有五桌,两列各(int主键& nvarchar值,加上索引)本地SQL CE数据库,以及有关在每个表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 seco nd执行。这是在添加任何其他需求之前,比如多个where子句,排名,排序等。即使我搜索我知道的数据库中的第一行,仍然需要大约5秒。

如果我改变方法和搜索一些非常常见的东西(如'the'),它只需要大约100ms执行。我知道Like与通配符比直接==比较复杂,但我不知道为什么表现如此不同。 (我知道这是一个无用的比较,因为它们是苹果和桔子,但我之前对用MySQL编写的相同数据库执行了类似的查询,并且无论我搜索的是什么,它们的结果一直在0.3-0.4s左右对于)。

我是否错过了一些非常明显的东西?我已经关注了微软的例子,并在线阅读了很多教程,但是我无法找到为什么这个查询太慢的原因。非常感谢您提供的任何建议。

+3

我强烈建议你尝试执行相同的查询*而不使用LINQ。*我怀疑*你会看到相同的性能,这意味着它不是LINQ应该归咎于所有。请记住,通过这样的通配符搜索,数据库基本上不能使用任何索引 - 而在直接匹配的情况下,它应该能够访问正确的输入非常迅速 –

+0

感谢您的快速回复,Jon。您说得对,我只是profi在我的桌面上使用生成的SQL引导了相同的数据库,并获得了类似的性能比(对于特定查询为1.2s,对于通用查询为0.02s)。我没有意识到通配符会有很大的性能影响。 – Superangel

+0

@Superangel:Nice UserName。 –

SIMPLE COMMON SENSE。

  • 您在低功率手机上运行该程序并进行表扫描查询。

SqlMethods.Like(t5.value, “%” + SEARCHTERM + “%”)

意味着没有索引抓斗,这是一个表扫描。

).Take(100);

表示:找到100个项目后停止。

现在,用一个非常常见的词(“the”),这可能意味着只有100个项目被处理。用一个更不寻常的词,它可能需要运行一半的表来获得100个项目。表扫描一半数据库将需要时间。 Simlpe。

一般来说,sql是为文本中的文本解析做好准备的 - 这就是为什么真正的sql server需要全文索引。在低pwoer硬件上运行(%word%)(wp7 =自然很慢)

这里指出LINQ是一个问题,绝对没有任何问题,LINQ将它转换为一个相当有效的SQL查询你在查询中定义的边界 - 这是你可以对数据库做的最糟糕的事情,遗憾的是,

+0

谢谢汤姆,我认为我的常识在盯着这么长时间以后一直低迷!你的解释非常清楚,我想我只是想过(希望?),不知怎的,我对Linq的理解缺乏责任。我想我需要重新制定我的查询和/或数据以避免这种通配类型的情况,但我很挣扎。无论如何,感谢您的时间,并指出什么应该是明显的:) – Superangel