【问题标题】:ASP.NET/SQL 2008 Performance issueASP.NET/SQL 2008 性能问题
【发布时间】:2011-06-12 13:58:07
【问题描述】:

我们开发了一个带有搜索屏幕的系统,看起来有点像这样:


(来源:nsourceservices.com

如您所见,有一些相当重要的搜索功能。您可以使用状态、渠道、语言、活动类型的任意组合,然后按名称等缩小范围。

然后,一旦您搜索并在底部弹出潜在客户,您就可以对标题进行排序。

查询使用 ROWNUM 执​​行分页方案,因此我们一次只返回大约 70 行。

问题

尽管我们只返回 70 行,但仍有大量 IO 和排序正在进行。这当然是有道理的。

这总是会导致磁盘队列出现一些小峰值。当我们达到 300 万个潜在客户时,它开始变得更加缓慢,而现在我们已经接近 5 个,磁盘队列有时会持续一两秒。

这实际上仍然可行,但是该系统还有另一个区域具有时间敏感的过程,为了简单起见,它是一个 Web 服务,需要非常快速地提供响应,否则会导致另一个超时结尾。磁盘队列峰值导致该部分陷入困境,从而导致下游超时。最终结果实际上是在我们基于 VoiceXML 的自动 IVR 中掉线,这对我们来说非常糟糕。

我们的尝试

我们已经尝试过:

  • 将系统中的引线数量减少到最低限度的维护任务。
  • 添加了明显的索引以提供帮助。
  • 在分析器中运行索引调整向导并应用了它的大部分建议。其中一个会或多或少地在索引中复制整个表,因此我手动对其进行了调整,使其做得更少。
  • 为服务器添加了更多 RAM。它有点低,但现在它总是有 8 gigs 空闲,并且 SQL 服务器配置为使用不超过 8 gigs,但它从不使用超过 2 或 3。我发现这很奇怪。为什么不只是将整个表放在 RAM 中?它只有 500 万个潜在客户,而且还有足够的空间。
  • 覆盖查询执行计划。我可以看到,此时索引似乎大部分都在完成它们的工作——大约 90% 的工作发生在排序阶段。
  • 考虑将 Leads 表分区到不同的物理驱动器,但我们没有资源,似乎没有必要这样做。

即将结束...

我的一部分感觉服务器应该能够处理这个问题。考虑到该服务器的强大功能,500 万条记录并不算多,这是一个不错的四核和 16 GB 内存。但是,我可以看到排序部分是如何导致数百万行被触摸而只返回少数。

那么在这种情况下你做了什么?我的直觉是我们也许应该削减一些功能,但如果有办法保持这一点完好无损,那将避免我与业务部门的战争。

提前致谢!

【问题讨论】:

  • 您在搜索 GUID 吗?你的聚集索引是什么?您是否考虑过在服务器中使用 SSD?你在做通配符搜索吗?如果是这样,您可能需要向后和向前索引 varchars
  • @Matthew PK:没有 GUID。聚集索引只是主键——LeadID (int)。至于固态驱动器......好吧,把钱扔在它上面是我最后的选择。但它在我的脑海里。 :)
  • 返回整个结果集并在客户端分页呢?作为用户,我宁愿提前多等 2 秒,也不愿每次页面都等待。
  • 查询是内置在动态 SQl 中还是固定查询?可能是查询本身需要调整而不是索引。
  • @Matthew PK:嗯,我实际上并没有考虑到这一点。问题是整个结果集可能多达数百万条线索,而在 ASP.NET 中,我相信这必须直接进入视图状态,除非我完全改变方向并在客户端 实际上 这样做使用某种 jQuery,或者可能使用 Silverlight 之类的东西。它似乎行不通,但老实说,我还没有涉足这种发展。你认为这是一个合法的选择吗?

标签: asp.net database optimization orm query-optimization


【解决方案1】:
  1. 确定最有可能运行哪些即席查询或使用存储过程限制搜索条件。您可以汇总数据吗?处理一下这个
    像数据仓库一样的应用程序。
  2. 为搜索中涉及的每个列创建索引以避免表扫描。
  3. 在表达式上创建片段。
  4. 随着更多潜在客户的加载,定期重新组织数据并更新统计信息。
  5. 将查询(结果集)创建的临时文件放入 ramdisk。
  6. 考虑迁移到 Informix OnLine 等高性能 RDBMS 引擎。
  7. 在查询时启动另一个线程以开始显示结果集中的 N 行
    继续执行。

【讨论】:

  • 好东西...此外,虽然您没有收到此错误,但步骤仍然适用:stackoverflow.com/questions/4719841/…
  • 除非您仔细控制查询(我猜 ORM 没有这样做),否则过多的索引可能会导致数据库尝试“万事通”计划而不是选择“给定类型搜索的最佳”索引。
  • 这真的很有趣,你有专门的工具来构建 ramdisk 吗?谷歌找到了 RamDisk 和 RamDisk plus。
  • @Brian:RamDisk Plus 11.. 您还必须考虑有多少用户同时执行查询。容量规划将决定您的应用需要多少 GB 的 RAM。
  • @BrianMacKay:是否可以启动另一个线程来开始显示搜索结果,即使查询尚未完成构建结果集?
【解决方案2】:

考虑您的 ORM 如何创建查询。 如果您的搜索性能很差,也许您可​​以尝试使用存储过程来返回您的结果,如有必要,还可以尝试使用专门针对正在使用的搜索条件定制的多个存储过程。

【讨论】:

    【解决方案3】:

    通常可以通过改进 SQL 查询来改善数据库瓶颈。在不知道它们是什么样子的情况下,考虑创建一个按计划填充的可操作数据存储或数据仓库。

    有时,扁平化复杂的关系数据库是可行的方法。它可以使查询运行得更快,并且使优化查询变得更加容易,因为模型非常平坦。这也可能使您更容易确定是否需要向上或向外扩展数据库服务器。容量和增长分析可能有助于做出这样的决定。

    事务性/高度规范化的数据库通常不像 ODS 或数据仓库那样可扩展。

    编辑:您的 ORM 可能也有它可能支持的优化,这可能值得研究,而不仅仅是研究如何优化它发送到数据库的查询。也许完全绕过您的 ORM 以获得报告可能是完全控制您的查询以获得更好性能的一种方法。

    【讨论】:

    • 又一个 ORM 倒在地上的地方。
    • 是的,ORM 非常适合某些场景,也许不是这个。如果解决方案需要保持面向 ORM 的情况,也许可以使用扁平化的数据库模型,使用简单的对象层来构造查询。我怀疑阻力最小的路径可能只是研究优化现有 ORM 查询的方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多