我有几个表,行数在 5M 到 1.5G 之间
每个表都有其 BLOB 字段,其大小从 100 字节到 30 兆字节不等,并存储为“行外大值类型”= ON
表存储在不同的文件组中,每个文件组有 3-4 个文件@不同的 LUN@非常快的 SAN
这些表每天增长 5-100 Gb 和 600k - 1.5M 行
经过一段时间后,从 2 周到 6 个月不等,一些行被删除或移动到存档数据库,因此 - 工作表中没有任何超过 6 个月的行。
服务器当前配置:
-T 3640; (消除了为存储过程中的每个语句向客户端发送 DONE_IN_PROC 消息。这类似于 SET NOCOUNT ON 的会话设置,但是当设置为跟踪标志时,每个客户端会话都以这种方式处理)
-T 1118;(将 tempDB 中的分配从一次 1pg(对于前 8 页)切换到一个范围。)
-T 2301;(启用特定于决策支持查询的高级优化。此选项适用于大型数据集的决策支持处理)
-T 1117;(一次增长所有数据文件,否则依次增长。)
-E; (增加为文件组中每个文件分配的区数。此选项对于运行索引或数据扫描的用户数量有限的数据仓库应用程序可能有用)
-T 834; (导致 SQL Server 对为缓冲池分配的内存使用 Windows …
我有一个综合测试,它重现了我们在生产环境中的一些错误。以下是重现它的 2 个脚本:
第一
DBCC TRACEOFF(-1,3604,1200) WITH NO_INFOMSGS;
SET NOCOUNT ON;
IF @@TRANCOUNT > 0 ROLLBACK
IF object_id('test') IS NOT NULL
DROP TABLE test
IF object_id('TMP_test') IS NOT NULL
DROP TABLE TMP_test
IF object_id('test1') IS NOT NULL
DROP TABLE test1
CREATE TABLE test(Id INT IDENTITY PRIMARY KEY)
GO
INSERT test DEFAULT VALUES
GO 2000
WHILE 1 = 1
BEGIN
CREATE TABLE TMP_test(Id INT PRIMARY KEY)
INSERT TMP_test SELECT * FROM test
WAITFOR DELAY '0:00:00.1'
BEGIN TRAN
EXEC sp_rename 'test', 'test1' …
Run Code Online (Sandbox Code Playgroud) 关于我想问的这个问题
比较两个查询:
(1)
DELETE dbA.dbo.tableA
FROM dbA.dbo.tableA a WITH(NOLOCK)
JOIN dbB.dbo.tableB b WITH(NOLOCK)
ON
b.colA = a.colA
AND b.colB = a.colB
Run Code Online (Sandbox Code Playgroud)
和
(2)
DELETE FROM dbA.dbo.tableA
WHERE EXISTS
(
SELECT *
FROM dbB.dbo.tableB b WITH(NOLOCK)
where
b.colA = dbA.dbo.tableA .colA
AND b.colB = dbA.dbo.tableA .colB
)
Run Code Online (Sandbox Code Playgroud)
很明显,如果我们不考虑可能导致脏读的并发写入,查询会做类似的工作。
但我有一个疑问
我对以下评论是否正确?
请注意,将从语句 (2) 的最开始放置一个共享(可升级?)锁 @tableA,而不是连接 (1) 中的两个 NOLOCK 表,这将放置第一个锁 - UX 锁仅在那里之后会找到要删除的第一行
我已经厌倦了向我们研发团队中的每个初级开发人员解释为什么他应该使用主键以及如何使用。所以我决定写一个小白皮书,每个新开发人员都应该阅读。这是它的草稿。
免责声明:
问题是- 我还应该在文档中添加什么?可能是——我应该改些什么呢?更详细的解释是什么?
草稿来了:
此外,即使使用具有(我希望)扁平分布的 SSN 或 ID Number,因为 PK 也不能解决 PK 的页面拆分问题,因为这些数字没有任何组织顺序。
sql-server ×4