Roy*_*mir 9 sql sql-server performance locking sql-server-2005
我有一个复杂的选择查询和一个巨大的表.
我正在运行此select语句,同时Update声明到达并尝试更新表.
恕我直言 - 更新需要独占锁 - 因此更新语句必须等到 select命令完成.
我对吗 ?
我该怎么做才能:执行复杂select,并让update命令运行(目前我不关心脏数据)
mar*_*c_s 15
是的 - 在某种程度上.
多长时间,SELECT取决于事务的隔离级别持有的共享锁:
READ UNCOMMITTED- 根本没有获得共享锁 - UPDATE未被阻止READ COMMITTED- 仅在读取数据期间获取共享锁 - UPDATE可能会在很短的时间内被阻止REPEATABLE READ并且SERIALIZABLE- 获取并保持共享锁,直到事务结束- UPDATE被阻塞直到SELECT事务结束从技术上讲,该UPDATE语句首先获得一个UPDATE锁 - 它与共享锁(由其使用SELECT)兼容- 在它读取要更新的行的当前值时的持续时间.
完成后,Update锁将升级为独占锁,以便将新数据写入表中.
当您同时运行两个语句(SELECT和UPDATE)时,实际行为基本上是随机的.这是因为这两种操作都不是即时的.为简化起见,请将表视为列表,SELECT正在遍历此列表,一次查看一行.UPDATE还尝试更新一行或多行.当UPDATE尝试更新SELECT 后面的行时,没有任何事情发生(没有阻塞),因为SELECT已经超过了UPDATE点.如果更新试图更新在其选择是寻找行,现在则更新将不得不等待选择继续前进,这将发生非常非常非常快,更新将解锁并取得成功,而在SELECT正在向前推进.但是如果UPDATE正在更新SELECT 之前的行,则更新将成功,稍后,SELECT将最终到达此行并将停止,阻止.现在SELECT必须等到执行UPDATE的事务提交.
这是简化的故事.现实生活要复杂得多.SELECT可以有多个读取点(并行计划).SELECT和UPDATE都需要选择访问路径,这意味着使用一个或多个辅助索引来定位行.复杂查询可能包含导致多次查找表的运算符(例如,连接).SELECT和UPDATE都可以进行书签查找以获取BLOB数据,这会显着改变锁定行为.基数估计可能导致SELECT以高粒度锁定模式运行(例如,表级共享锁).UPDATE可以触发锁升级,升级可能会失败或成功.选择不同的访问路径可能会导致死锁.由于散列冲突,可能会发生错误的锁争用.只有一个无数变量在这里有发言权.我甚至没有提到更高的隔离级别(可重复读取,可序列化).
也许您应该使用SNAPSHOT隔离并停止担心这个问题?
| 归档时间: |
|
| 查看次数: |
11968 次 |
| 最近记录: |