为了将应用程序与我们的整体数据库分离,我们尝试将各种表的 INT IDENTITY 列更改为使用 COALESCE 的 PERSISTED 计算列。基本上,我们需要解耦应用程序能够更新数据库以获取跨多个应用程序共享的公共数据,同时仍然允许现有应用程序在这些表中创建数据,而无需修改代码或过程。
所以基本上,我们已经从列定义转移到了;
PkId INT IDENTITY(1,1) PRIMARY KEY
Run Code Online (Sandbox Code Playgroud)
到;
PkId AS AS COALESCE(old_id, external_id, new_id) PERSISTED NOT NULL,
old_id INT NULL, -- Values here are from existing records of PkId before table change
external_id INT NULL,
new_id INT IDENTITY(2000000,1) NOT NULL
Run Code Online (Sandbox Code Playgroud)
在所有情况下,PkId 也是一个 PRIMARY KEY,在所有情况下,除了一种情况,它是 CLUSTERED。所有表都具有与以前相同的外键和索引。本质上,新格式允许解耦应用程序提供 PkId(作为 external_id),但也允许 PkId 作为 IDENTITY 列值,因此允许通过使用 SCOPE_IDENTITY 和 @@IDENTITY 依赖 IDENTITY 列的现有代码像以前一样工作。
我们遇到的问题是,我们遇到了几个查询,这些查询曾经在可接受的时间内运行,现在完全失败了。这些查询使用的生成的查询计划与以前完全不同。
鉴于新列是 PRIMARY KEY、与以前相同的数据类型和 PERSISTED,我希望查询和查询计划的行为与以前相同。在 SQL Server 将如何生成执行计划方面,COMPUTED PERSISTED INT PkId 的行为是否应该与显式 INT 定义基本相同?您可以看到这种方法还有其他可能的问题吗?
进行此更改的目的应该是允许我们更改表定义,而无需修改现有过程和代码。鉴于这些问题,我认为我们不能采用这种方法。