我是SQL DBA角色的新手。我有一个可能每天运行多次的存储过程(SP1)。它在table1上运行一个昂贵的SELECT
,可能需要15分钟才能完成。我有另一个存储过程(SP2)在table1上运行SELECT
,可能需要1秒钟才能完成。
SP1运行后,SP2必须等到SP1完成!有没有什么方法可以获得所需的资源(比如从table1中选择)来运行SP2,在SP2完成之后,将它还原回SP1?
我不想使用SELECT WITH (NOLOCK)
,因为其他查询可能会尝试编辑table1。
答案 0 :(得分:1)
你肯定需要首先在非生产环境中测试它,但它应该是NOLOCK
的替代
然而,联机丛书说:
快照隔离的最终效果是,事务会查看事务开始时存在的所有数据,而不会在基础表上保留或放置任何锁定。这可以在存在争用的情况下提高性能。
这里有一个警告,它可能对你的TempDB 有害,但如果你有足够的空间,它可能对你有所帮助。
我肯定会首先阅读它,也许可以查看其他answers。
答案 1 :(得分:1)
你问题的简单答案是“不”。看起来你在SP1中有一个长时间运行的查询,它在Table1中采用共享锁,这样SP2中的任何UPDATE
或INSERT
都必须等到SP1完成,以便可以采取必要的独占锁(你没有提到事务/隔离级别,所以我假设它是SELECT
本身需要时间而不是任何后续处理 - 尽管你已经说过SP1可能会执行一些UPDATE
s或INSERT
自己的)。根据我的收集,您希望SP1在其SELECT
中释放其锁,以便SP2可以执行其UPDATE
,然后,一旦SP2释放其锁,然后允许SP1继续其{ {1}}。我担心这违反了SQL的锁定逻辑,实际上违反了ACID原则。为了确保一致的结果,每次SP2(或其他进程)执行SELECT
时,SP1必须重新启动SELECT
,这会对数据库性能造成灾难性后果。
听起来您需要考虑重构存储过程/应用程序。让SP定期运行需要15分钟并且可能锁定表听起来像是一个主要的瓶颈。它是否可以分解 - 可能将SP2的一些逻辑纳入其中一个段?另外,为什么需要这么长时间?是否没有可用于减少UPDATE
所需时间的索引,还避免了您似乎遇到的那种表/范围锁?