代码之家  ›  专栏  ›  技术社区  ›  Iravanchi

在同步查询调用中,一个查询导致另一个查询运行较慢。为什么?

  •  -1
  • Iravanchi  · 技术社区  · 16 年前

    很抱歉提出这么长的问题,但我认为这是一个有趣的情况,我找不到任何解释:

    我参与了一个应用程序的优化,该应用程序在一个专用SQL Server数据库上执行了大量连续的SELECT和INSERT语句。

    我使用了一个探查器(JProfiler——应用程序基于Java)来确定应用程序的每个部分需要多少时间。结果表明,60%的时间用于插入方法调用,近20%的时间用于选择调用(其余时间分布在其他部分)。

    经过一些试验,我得出了这样的结论:我 注释掉 占用60%时间的插入查询。我预计总运行时间大约为35分钟,因为我已经删除了90分钟中的60%。但是整个过程都花了同样的90分钟(只做选择,不做其他事情),但是每次选择都花了更长的时间!

    一切都在运行同步,没有异步调用。只有一个执行线程。SELECT和INSERT查询非常简单,没有任何特殊的功能,它们位于不同的表上,但位于同一个数据库上。

    我在应用程序机器和远程网络机器上使用DB进行了测试。

    对此我想不出任何解释,因为探查器(应用程序探查器,而不是SQL探查器)报告了方法调用时间的变化,并且通过删除INSERT语句,SELECT语句的运行时间更长。

    有人能给我解释一下会发生什么事吗?

    (不可能有缓存/查询优化的东西,因为查询是同步运行的,并且在一个线程中运行,它对缓存的影响远没有这么大)

    4 回复  |  直到 16 年前
        1
  •  1
  •   Mark Storey-Smith    16 年前

    可能是插入件:

    a) 影响表/索引统计信息,因此选择了更好的selects执行计划。

    b) 将选择器所需的数据保留在缓冲区中。

    在这两个测试期间进行SQL探查器跟踪,并通过跟踪清理器运行输出( http://msdn.microsoft.com/en-us/library/aa175800%28sql.80%29.aspx ).

        2
  •  1
  •   Remus Rusanu    16 年前

    您的应用程序在数据库调用时被阻止。当您第一次测量时,阻塞发生在INSERT上,因为可能那些恰好是最先阻塞的调用。当您删除插入时,客户端代码向前移动,并在下一次调用时阻塞,选择。这里真的没有什么特别的,您只是删除了一个调用,所以应用程序只是在下一个调用中被阻塞。

    您真正需要调查的是数据库阻塞。忘记客户端JProfiler和任何类似的东西。而是关注数据库上发生的事情,并使用数据库trobleshooting方法。您的问题很可能是争用和锁定阻塞。

    只要查看服务器上的进程列表,就可以立即看到明显的问题( sys.dm_exec_requests Waits and Queues 方法论

        3
  •  0
  •   gbn    16 年前

    但是,如果没有一些带有模式的SQL示例,则很难判断。

        4
  •  0
  •   Mitch Wheat    16 年前

    您需要考虑插入表上的索引数量以及这些索引的定义和状态。

    一种可能是插入导致大量页面拆分。另一个原因是您没有任何索引,导致SELECT查找进行表扫描。

    在执行插入之前,请尝试重建索引,并调查索引的填充因子有多大。对于具有高插入的表,我通常将其设置为75%(而不是默认设置为90%),但您需要考虑行大小,因为这将增加所需的总页数。