我正在尝试在 Azure SQL 数据库上重建大表 (77GB) 的聚集索引。表上有高并发事务活动,因此我正在使用该ONLINE=ON
选项。
这对于较小的表很有效;但是,当我在这个大表上运行它时,它似乎在表上使用了排他锁。我不得不在 5 分钟后停止它,因为所有事务活动都超时了。
来自 SPID 199 的会话:
ALTER INDEX PK_Customer ON [br].[Customer]
REBUILD WITH (ONLINE = ON, RESUMABLE = ON);
Run Code Online (Sandbox Code Playgroud)
从另一个会话:
在相同的结果中更进一步:
我知道在线重建可以在过程开始和结束时锁定“短”持续时间。但是,这些锁定会持续几分钟,这并不完全是“短”持续时间。
在重建运行时,我运行了SELECT * FROM sys.index_resumable_operations;
但它返回了 0 行,就好像重建根本没有开始一样。
较小的表也有一个可能大于 900 字节的 PK,并且相同的ALTER
语句在没有任何长时间阻塞的情况下工作,所以我认为它与 PK 大小无关。这些较小的表也有相似数量的nvarchar(max)
列。我能想到的唯一真正的区别是这个表有更多的行。
这是 的完整定义br.Customer
。没有外键或非聚集索引。
CREATE TABLE [br].[Customer](
[Id] [bigint] NOT NULL,
[ShopId] [nvarchar](450) NOT NULL,
[accepts_marketing] [bit] NOT NULL,
[address1] [nvarchar](max) MASKED WITH …
Run Code Online (Sandbox Code Playgroud) sql-server clustered-index azure-sql-database index-maintenance online-operations
我认为自己是 Sql Server 锁定的初学者。
我的理解是,在使用 RCSI 时,Sql Server 不需要发出 S 锁,因为它使用行版本控制(在大多数情况下)。从http://technet.microsoft.com/en-us/library/jj856598(v=sql.110).aspx我们可以阅读以下关于 U 锁的信息:
用于可以更新的资源。防止在多个会话读取、锁定和稍后可能更新资源时发生的常见死锁形式。
知道了这一点,为什么Sql Server 需要发出U 锁(使用RCSI 时)?在我看来,Sql Server 可以简单地读取行,并在必须执行更新时直接请求 X 锁。
我一直在考虑这个的原因是因为我在更新同一个表的 2 个会话中遇到了死锁。像这样(为了清楚起见而简化):
第 1 节:
BEGIN TRAN
UPDATE t1 SET col1 = col1 + 100 WHERE col2 = value1
UPDATE t1 SET col1 = col1 + 100 WHERE col2 = value2
UPDATE t1 SET col1 = col1 + 100 WHERE col2 = value3
Run Code Online (Sandbox Code Playgroud)
第 2 节:
BEGIN TRAN
UPDATE t1 SET col1 = col1 …
Run Code Online (Sandbox Code Playgroud) sql-server deadlock locking isolation-level snapshot-isolation
当我从 sql server management studio 导出 sql azure 数据库作为数据层应用程序时,我可以选择勾选某些表,但这些表不包含在结果文件中。
我想导出这些表模式,但忽略它们的数据(本质上是导入空表)。对于所有其他表,我也想要数据。
有可能这样做吗?
假设我们有一个 Product 表(product_id、product_name)和一个 Sales 表(product_id、date、qty、amount)。
什么 sql 查询会返回每个产品的月销售额,并包括没有销售额的产品?
(如果这有什么不同,我正在使用 sql server )。
澄清:我希望每个可能的月份/产品元组都有一行。如果给定月份/产品没有销售额,则应显示零数量/销售额