【问题标题】:SQL Server Multiple calls to the same Stored Procedure affects performance?SQL Server 多次调用同一个存储过程会影响性能吗?
【发布时间】:2015-01-10 21:39:36
【问题描述】:

我有一个类似于下面的SP:

DECLARE my_cursor CURSOR FAST_FORWARD FOR 
SELECT TOP 500 id
FROM Table
WHERE colA= 1 AND colB= colC
--call another SP
--some other select/update operations
-- deallocate the cursor when everything is done

现在,假设我有一个循环调用该 SP 的 Java 程序:

for (int i =0; i < 1000; i++)
     JPA.em().createNativeQuery("exec my_SP").executeUpdate(); //each time gets 500 to process

我意识到处理时间正在逐渐增加。完成第一个循环只需要几秒钟,但很快就需要大约一分钟才能完成一个循环。

我猜这是由于内存不足,因为每个循环 SP/光标都占用了一些内存空间。因此,最终 SQL Server 需要回收一些内存,并且随着循环的进行,这会变得更加频繁(因此需要更长的处理时间)。

我有两个问题:

  1. 如果以上是正确的,为什么增加的时间在某个点之后不能相当稳定?每次我处理恒定数量(500)的记录时。所以,我想,就内存而言,它就像 500 out 和 500 in。
  2. 如果上述不正确,为什么每个循环的处理时间都会增加?
  3. 是光标是主要原因,还是因为我将SP调用分成了,比如在这种情况下,一千个?

【问题讨论】:

  • 令人讨厌的光标!
  • 同意...但我真的很想知道光标是否是原因。或者是因为我将 SP 调用分成了一千个片段?
  • 你的问题根本和Java无关。
  • 两者...您正在使用循环来调用存储过程,而存储过程又使用循环。
  • @路易吉。感谢您消除它,我添加了标签以防万一......我不能确定。

标签: sql sql-server stored-procedures


【解决方案1】:

我相信您的问题与数据库锁定有关。

您正在触发同一查询的许多线程,所有这些线程都在互相妨碍。 SQL Server 应用读锁来防止幻读,但主锁将是需要写锁的更新语句。其他线程必须等到它被释放才能继续,因此形成等待线程的积压,否则称为 Db 阻塞。

您可以通过注释掉 SQL 更新语句来进行试验,并且您可能还需要在脚本顶部添加以下行以进行测试:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

你应该想办法加快速度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    相关资源
    最近更新 更多