提高大型数据集的搜索性能

时间:2011-03-31 11:56:40

标签: c# sql sql-server

在已经投入生产的WPF应用程序中,用户有一个窗口,用于选择客户端。它显示了包含所有客户端的列表和一个可以搜索客户端的TextBox。

随着客户群的增加,这种速度异常缓慢。大约1分钟的操作,每天发生约100次。

目前,MSSQL管理工作室表示查询select id, name, birth_date from client需要41秒才能执行(大约130000行)。

对于如何改善这段时间有什么建议吗?代码上的索引,ORM或直接sql查询?

目前我正在使用框架3.5和LinqToSql

5 个答案:

答案 0 :(得分:4)

如果您的查询实际上是SELECT id, name, birth_date from client(即没有where子句),那么您可以做的很少,以加快新硬件的速度。 SQL Server必须进行表扫描才能获得所有数据。即使覆盖索引也意味着它必须扫描与表一样大的索引。

您需要问自己的是:130000个客户列表对您的用户真正有用吗?我真的要滚动到列表中的第75613条,找到他们想要的用户吗?答案可能不是。我只会选择搜索选项。至少那时你可以添加对这些查询有意义的索引。

如果您确实需要整个列表,请尝试以块的形式加载它。从前500条记录开始,然后在用户移动滚动条时添加更多记录。这样就减少了初始加载时间,用户只会加载必要的数据。

答案 1 :(得分:3)

为什么需要所有客户的清单?你不能只是拥有你描述的搜索TextBox并在服务器端处理搜索查询。在那里,您为单个客户端搜索的最大返回行数设置上限(例如,最多500个匹配)。

或者,可以通过在Web服务器上缓存客户端数据列表来获得一些效率提升

答案 2 :(得分:2)

根据您的查询,索引不应该有用。您可以使用一个缓存已排序查询的视图(假设您没有按ID排序?),但鉴于SQL Server的adhoc查询的烘焙查询缓存,您可能不会在那里看到太大的收益。 ORM确实增加了一些开销,但有几个教程可以降低成本(例如http://www.sidarok.com/web/blog/content/2008/05/02/10-tips-to-improve-your-linq-to-sql-application-performance.html)。适用于您的要点是尽可能使用已编译的查询,并为只读数据关闭乐观并发。

通过让您的客户直接点击数据库,可以实现更大的性能提升。如果你在那里添加一个服务层(不一定是web服务,但它可能是),那么服务类或应用程序可以放置一些智能缓存,这对于像这样的只读查询有一个数量级的帮助。

答案 3 :(得分:1)

进入SQL Server,进行新的查询。在“查询”菜单中,单击“包括客户端统计信息”。

运行查询就像在代码中一样。 它将显示结果以及名为“客户统计”

的结果旁边的选项卡

点击它并查看“服务器回复的等待时间”中的时间。这是ms,这是服务器实际执行的时间。

我刚刚运行了这个查询:

select  firstname, lastname from leads

服务器上花了3ms来获取301,000条记录。

“总执行时间”类似于483ms,其中包括SSMS实际获取数据并处理数据的时间。我的查询需要2.5-3s才能在SSMS中运行,剩下的时间(2500ms左右)实际上是SSMS绘制结果等。)

我的猜测是,41秒可能没有花在SQL服务器上,因为130,000条记录确实不是那么多。在SQL服务器返回结果之后,41秒可能主要用于所有内容。

如果发现SQL Server需要很长时间才能执行,请在查询菜单中启用“包含实际执行计划”,然后重新运行查询。出现一个名为“执行计划”的新选项卡,此选项卡将显示当您对此表执行选择时SQL服务器正在执行的操作以及它花费所有时间的百分比。就我而言,它在100%的时间内用于PK_Leads的“聚集索引扫描”

已修改为包含更多统计资料

答案 4 :(得分:0)

一般来说:

  1. 找出花费这么多时间,执行查询或检索结果的内容
  2. 如果查询执行,查询计划将告诉您哪些索引丢失,只需按下SSMS中的显示查询计划按钮,您将获得有关应创建哪些索引以提高性能的提示
  3. 如果要检索这些值,除了升级硬件(ram,磁盘,网络等)之外,你无能为力。
  4. 但:
    在您的情况下,它看起来像查询是全表扫描,这对性能无益,请检查您是否确实需要一次检索所有这些数据。
    由于没有任何条款,因此查询执行不太可能是问题所在。意味着其他索引无济于事。

    您需要更改应用程序访问数据的方式。不是将所有客户端加载到内存中,然后在内存中搜索它们,而是需要将搜索项传递给数据库查询。

    LinqToSql使您可以使用不同的功能来搜索值,这里有一个描述其中大部分的博客: http://davidhayden.com/blog/dave/archive/2007/11/23/LINQToSQLLIKEOperatorGeneratingLIKESQLServer.aspx