Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 提高大型数据集中的搜索性能_C#_Sql_Sql Server - Fatal编程技术网

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

C# 提高大型数据集中的搜索性能,c#,sql,sql-server,C#,Sql,Sql Server,在已经投入生产的WPF应用程序上,用户有一个窗口,可以在其中选择客户端。它显示了一个包含所有客户端的列表和一个文本框,用户可以在其中搜索客户端 随着客户群的增加,这变得异常缓慢。每天进行100次左右的手术大约需要1分钟 目前,MSSQL management studio表示,从客户端选择id、姓名、出生日期的查询需要41秒才能执行(大约130000行) 这次有什么改进的建议吗?索引、ORMs或直接sql查询代码 目前,我通常使用框架3.5和LinqToSql: 找出执行查询或检索结果所花费的时

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

随着客户群的增加,这变得异常缓慢。每天进行100次左右的手术大约需要1分钟

目前,MSSQL management studio表示,从客户端选择id、姓名、出生日期的查询需要41秒才能执行(大约130000行)

这次有什么改进的建议吗?索引、ORMs或直接sql查询代码

目前,我通常使用框架3.5和LinqToSql:

  • 找出执行查询或检索结果所花费的时间
  • 如果是在执行查询时,查询计划将告诉您缺少哪些索引,只需按SSMS中的“显示查询计划”按钮,您将获得有关应创建哪些索引以提高性能的提示
  • 如果是检索值,那么除了升级硬件(ram、磁盘、网络等)之外,您也无能为力
  • 但是:
    在您的情况下,查询看起来像是一个完整的表扫描,这对性能从来都不好,请检查您是否真的需要一次检索所有这些数据。
    因为没有子句,所以问题不太可能出在查询执行上。这意味着额外的索引将无济于事。

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

    LinqToSql使您能够使用不同的功能来搜索值,下面是一个博客,介绍了其中的大部分功能:

    根据您的查询,索引应该没有帮助。您可以使用一个缓存已排序查询的视图(假设您不是按id排序?),但考虑到SQL Server针对临时查询的烘焙查询缓存,您可能也不会看到太多好处。ORM确实增加了一些开销,但是有一些教程可以用来降低成本(例如)。适用于您的要点是尽可能使用编译查询,并关闭只读数据的乐观并发


    通过让客户机不直接访问数据库,可以实现更大的性能增益。如果在其中添加一个服务层(不一定是web服务,但也可以是),那么服务类或应用程序可以放置一些智能缓存,这对这样的只读查询会有很大帮助。

    为什么需要所有客户端的列表?难道你不能在服务器端使用描述和处理搜索查询的搜索文本框吗。在这里,您可以为单个客户端搜索设置最大返回行数上限(例如,最大500个匹配项)


    或者,如果您的查询实际上是
    从客户机选择id、姓名、出生日期(即无where子句),则可以通过在web服务器上缓存客户机数据列表来实现一些效率提高。除了新的硬件,您几乎无法加快速度。SQL Server必须进行表扫描才能获取所有数据。即使是覆盖索引也意味着它必须扫描与表一样大的索引

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


    如果您确实需要整个列表,请尝试将其惰性地分块加载。从前500条记录开始,然后随着用户移动滚动条添加更多记录。这样可以缩短初始加载时间,用户只加载必要的数据。

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

    像从代码中运行查询一样运行查询。 它将显示结果,并在结果旁边显示一个名为“客户端统计信息”的选项卡

    单击该按钮,查看“等待服务器回复时间”中的时间,单位为毫秒,这是服务器实际执行的时间

    我刚刚运行了这个查询:

    select  firstname, lastname from leads
    
    在服务器上获取301000条记录需要3毫秒

    “总执行时间”大约为483ms,其中包括SSM实际获取和处理数据的时间。我的查询在SSMS中运行了大约2.5-3秒,剩下的时间(2500毫秒左右)实际上是SSMS绘制结果等。)

    我的猜测是,这41秒可能没有花在SQL server上,因为130000条记录实际上并不多。在SQL server返回结果之后,您的41秒可能大部分时间都花在了所有事情上

    如果发现SQL Server执行时间过长,请在“查询”菜单中启用“包含实际执行计划”重新运行查询。此时会出现一个名为“执行计划”的新选项卡。此选项卡将显示在该表上执行选择操作时SQL server正在执行的操作,以及SQL server花费所有时间的百分比。在我的例子中,它100%的时间都花在PK_线索的“聚集索引扫描”上


    编辑以包含更多统计信息

    查询中没有任何子句,因此即使是完整的表扫描,这里也很可能没有索引有帮助。FWIW请确保表具有主键130000行不是SQL的记录集那么大。我怀疑问题实际上是SQL,即使没有where子句,也不应该使用41s。@Polity:+1进行评论。您提到的DataVirtualization文章链接似乎正好符合OP的要求