从其他编程语言转向 SQL,递归查询的结构看起来很奇怪。一步步走过来,仿佛分崩离析。
考虑以下简单示例:
CREATE TABLE #NUMS
(N BIGINT);
INSERT INTO #NUMS
VALUES (3), (5), (7);
WITH R AS
(
SELECT N FROM #NUMS
UNION ALL
SELECT N*N AS N FROM R WHERE N*N < 10000000
)
SELECT N FROM R ORDER BY N;
Run Code Online (Sandbox Code Playgroud)
让我们来看看吧。
首先,执行锚成员并将结果集放入 R。因此 R 被初始化为 {3, 5, 7}。
然后,执行低于 UNION ALL 并且第一次执行递归成员。它在 R 上执行(即,在我们目前手头的 R 上:{3, 5, 7})。这导致 {9, 25, 49}。
这个新结果有什么用?它是否将 {9, 25, 49} 附加到现有的 {3, 5, 7},标记结果联合 R,然后从那里继续递归?或者它是否将 R 重新定义为这个新结果 {9, 25, 49} 并在以后进行所有联合?
两种选择都没有意义。 …
我们是一个数学家团队(即,没有 DBA 经验)。
我们在 SQL Server 2012 中有一个大型数据库。它有超过 2 TB 的数据(数百个表,每个表有数百万行和数百列宽)。每个月,我们都会收到一系列数据的添加和修订,这要求我们通过删除、替换或更新大部分或所有表来对数据库进行大量更新。
我们的工作主要集中在制定 SQL 逻辑来计算我们需要的结果。我们没有运行实时呼叫中心。我们根据需要应用了一些索引,我们对性能非常满意。
问题是日志文件。自然地,日志文件随着如此多的数据操作而增长和增长。我们的日志文件目前大约为 1 TB。我们有大量的磁盘空间,但不是无限的。
根据我们在 Internet 上的阅读,我们了解到日志文件对于事务完整性、回滚和恢复是必需的。但就我们的特定目的而言,我们并不关心这些。我们可能永远不会执行回滚,也永远不会尝试恢复。更糟糕的是,我们只需再次下载数据文件并从头开始创建一个新数据库。
我们真的只是希望日志文件消失并且永远不会回来。
我们将数据库恢复模式设置为简单,天真地认为这意味着“无恢复模式”,但我们很快就消除了这些幻想。
我们也明白有很多错误的事情不能做(分离、收缩等)。我们只是不知道正确的做法。
也许有人会建议我们设置日志文件增长的限制。但是,这留下了两个问题:(1) 我们如何摆脱已经存在的 1 TB?(2) 我们之前尝试过,当我们接近指定的限制时,我们开始在这里、那里和任何地方收到错误 9002(日志文件已满)。所以现在我们害怕应用大小限制。
我们如何在没有任何伤害的情况下告诉数据库“没有日志文件,请”?
我们是一个数学家团队(即,没有 DBA 经验)。
我们正在从旧服务器盒 (SQL Server 2012) 迁移到新服务器盒 (SQL Server 2017)。对于旧服务器上的每个数据库,我们制作了一个备份副本,将其移植到新服务器,并从备份文件中将其恢复到完整的数据库荣耀。
到现在为止还挺好。
但是,我们的入住日期有所延迟,我们仍在使用旧服务器。随着我们继续在旧服务器上工作,这些数据库中的更改继续累积。因此,这意味着位于新服务器上的复制数据库现在已过时且已过时。(讽刺,不是吗?)
对于那些已更改的数据库,我们知道我们最终必须制作新的备份副本并将其移植到新服务器上。
到了时候,在恢复最新的备份副本之前摆脱新服务器上那些现在已经过时的数据库的最聪明方法是什么?
我们担心如果我们不小心,使用相同的名称,可能会发生一些遮挡或遮蔽。在恢复最新版本之前,我们希望确保新服务器上的过时副本完全消失。
我们要计算表中每一行的总“行上”存储字节数。正如我们所理解的,我们必须将每一列的 DATALENGTH() 相加,同时还要考虑 NULL 和诸如 VARCHAR(MAX) 之类的东西,它们在“行”上只有一个 24 字节的指针。我们知道每一行也有一些开销,这在下面的查询中没有考虑。
SELECT ROW_ID,
CASE
WHEN COLUMNPROPERTY(OBJECT_ID('EXAMPLE_TABLE'),'COL1','PRECISION') = -1 THEN 24
ELSE ISNULL(DATALENGTH(COL1), 1)
END
+
CASE
WHEN COLUMNPROPERTY(OBJECT_ID('EXAMPLE_TABLE'),'COL2','PRECISION') = -1 THEN 24
ELSE ISNULL(DATALENGTH(COL2), 1)
END
+
CASE
WHEN COLUMNPROPERTY(OBJECT_ID('EXAMPLE_TABLE'),'COL3','PRECISION') = -1 THEN 24
ELSE ISNULL(DATALENGTH(COL3), 1)
END
+
...
...
AS ROW_SIZE
FROM EXAMPLE_TABLE
ORDER BY ROW_SIZE DESC
;
Run Code Online (Sandbox Code Playgroud)
多么野兽!而且这只是一个近似值。
然后我们发现
DBCC SHOWCONTIG ('EXAMPLE_TABLE') WITH TABLERESULTS
Run Code Online (Sandbox Code Playgroud)
返回最大记录大小。这表明 SQL Server 中已经有一个算法可以计算行的确切大小。
我们如何直接访问该算法?