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

时间:2011-11-01 07:41:21

标签: c# sql linq-to-sql windows-phone-7

我在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'),则只需要 100ms 来执行。我知道Like使用通配符比直接==比较更复杂,但我不知道为什么性能如此不同。

(我知道这是一个无用的比较,因为它们是苹果和橘子,但我之前在用MySQL编写的同一个数据库上执行了类似的查询,并且无论我搜索的是什么,它们始终在0.3-0.4s左右得到结果)。

我错过了一些非常明显的东西吗?我已经按照微软的例子在网上阅读了很多教程,但我找不到这个查询速度如此之慢的原因。非常感谢您提出的任何建议。

1 个答案:

答案 0 :(得分:3)

简单的常识。

  • 您可以在低功耗手机上运行该功能并进行表扫描查询。
  

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

表示没有索引抓取,这是表扫描。

  

)取(100)。

表示:找到100件物品后停止。

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

一般来说,sql在文本中对单词解析做了很多准备 - 这就是为什么真正的sql server是全文索引的原因。在低价硬件上运行(%word%)(wp7 =自然很慢。

这里绝对没有任何内容指出LINQ是一个问题。 LINQ在您在查询中定义的性能边界内转换为非常有效的SQL查询 - 遗憾的是,这是您可以对数据库执行的最糟糕的事情。