多线程/并行插入和哈希分区中的 SQL Server 锁存

1 database-design sql-server concurrency partitioning hashing

我们正在 SQL 服务器表中进行并行、多线程插入,并希望减少闩锁。

利用散列分区来减少闩锁的缺点是什么?从本质上查询所有这些拆分的分区表是否降低了查询速度?

我们有大约 120 表插入每秒,金融系统。

其他注意事项:SQL 2016 系统每年将使用大约 50 GB 的 SSD 硬盘空间。目前,拥有 50 个核心处理器和 150 GB 的 RAM。

平台未搭建,所以没有基线测试;但我需要制定测试计划和策略。

哈希分区示例: http : //www.madeiradata.com/how-to-solve-the-tail-insert-problem-2/

CREATE PARTITION FUNCTION pf_hash (TINYINT) 
AS RANGE LEFT FOR VALUES (0,1,2,3,4,5,6,7,8);

CREATE PARTITION SCHEME ps_hash 
AS PARTITION pf_hash ALL TO ([PRIMARY]);

CREATE TABLE dbo.UserEntries_RegularWithHash 
(   
Id BIGINT IDENTITY NOT NULL,
UserId INT NOT NULL ,
CreatedDate DATETIME2 NOT NULL,
HashId AS CAST(Id % 9 AS TINYINT) PERSISTED NOT NULL,
CONSTRAINT PK_UserEntries_RegularWithHash 
PRIMARY KEY CLUSTERED (Id,HashId)
) 
ON ps_hash(HashId);
Run Code Online (Sandbox Code Playgroud)

Dan*_*man 6

未指定分区列的查询将需要访问所有分区。对于使用计算散列列分区的表来说,这尤其是一个问题,因为散列值通常不在查询中指定。尽管您可以指定该HashId值,但这样做并不自然。例子:

--touches all 10 partitions
SELECT *
FROM dbo.UserEntries_RegularWithHash
WHERE Id = @Id;

--touches 1 partition
SELECT *
FROM dbo.UserEntries_RegularWithHash
WHERE Id = @Id
AND HashId = CAST(@Id % 9 AS TINYINT);
Run Code Online (Sandbox Code Playgroud)

对具有增量键的非分区表的闩锁争用通常只发生在非常高的插入率下。

在每秒 120 次插入的情况下,不会在运行状况良好的机器上发生闩锁争用。David Browne-Microsoft建议每秒 10,000 次插入是闩锁争用的问题。这可能是一个很好的 SWAG,因为它取决于行大小和硬件等因素。我认为可以假设在考虑闩锁争用之前需要每秒几千的速率。那时您可能会考虑内存中 OLTP 表和/或批量/批量插入。

我听说过早优化是万恶之源。在这种情况下,我当然不会仅仅为了避免闩锁争用而引入分区。