【问题标题】:Reduce database to subset of data in tables that are joined together将数据库缩减为连接在一起的表中的数据子集
【发布时间】:2026-01-15 23:10:01
【问题描述】:

我想获取基于 SQL Server 数据库的数据子集,这样我就可以为应用程序运行一些冒烟测试。我的典型工作流程如下,但删除查询需要一个多小时,因为 X、Y 和 Z 中有数亿行。我怎样才能让它更快?为了清楚起见,请在您的答案中使用 T-SQL 代码。

  • 通过为每个表运行以下命令来备份每个表:

    SELECT * INTO BACKUP_SRC_PATIENT FROM [SRC_PATIENT] -- has PK patient_id
    SELECT * INTO BACKUP_SRC_X FROM [SRC_X] -- has FK patient_id
    SELECT * INTO BACKUP_SRC_Y FROM [SRC_Y] -- has FK patient_id
    SELECT * INTO BACKUP_SRC_Z FROM [SRC_Z] -- has FK patient_id
    
  • 删除除 100 名患者以外的所有患者

    DELETE FROM [SRC_PATIENT] 
    WHERE [PATIENT_ID_NONNUM] NOT IN 
          (SELECT top 100 [PATIENT_ID] FROM [SRC_PATIENT]
           WHERE BLA = 'BLA')
    
  • 从 SRC_X、SRC_Y 和 SRC_Z 中删除数据,其中患者 ID 不在 SRC_PATIENT 中

    DELETE FROM [SRC_X] 
    WHERE [PATIENT_ID] NOT IN 
          (SELECT [PATIENT_ID] FROM [SRC_PATIENT])
    
    DELETE FROM [SRC_Y] 
    WHERE [PATIENT_ID] NOT IN 
          (SELECT [PATIENT_ID] FROM [SRC_PATIENT])
    
    DELETE FROM [SRC_Z] 
    WHERE [PATIENT_ID] NOT IN 
          (SELECT [PATIENT_ID] FROM [SRC_PATIENT])
    

【问题讨论】:

  • 我不是。在运行删除命令之前,有数以百万计的行。不是回归测试。这发生在我们的 QA 环境中。我们只是在这个数据库中运行单元测试。但即使在对数千名患者进行单元测试之前,我也会对 100 名患者进行一些简单的烟雾测试。
  • 表上有哪些索引?

标签: sql-server sql-server-2008 tsql sql-delete


【解决方案1】:

而不是删除除 100 之外的所有行 - 截断表并从备份中复制超过 100 行。

TRUNCATE 从表中剪切所有数据,而不必逐行(或逐页)删除它们:

TRUNCATE TABLE [SRC_PATIENT]
TRUNCATE TABLE [SRC_X]
TRUNCATE TABLE [SRC_Y]
TRUNCATE TABLE [SRC_Z]

INSERT INTO [SRC_PATIENT]
SELECT TOP 100 * FROM [BACKUP_SRC_PATIENT]
WHERE BLA = 'BLA' 

INSERT INTO [SRC_X]
SELECT * FROM [BACKUP_SRC_X]
WHERE [PATIENT_ID] IN (SELECT [PATIENT_ID] FROM [SRC_PATIENT])

INSERT INTO [SRC_Y]
SELECT * FROM [BACKUP_SRC_Y]
WHERE [PATIENT_ID] IN (SELECT [PATIENT_ID] FROM [SRC_PATIENT])

INSERT INTO [SRC_Z]
SELECT * FROM [BACKUP_SRC_Z]
WHERE [PATIENT_ID] IN (SELECT [PATIENT_ID] FROM [SRC_PATIENT])

【讨论】:

  • 或者点击事务日志。
  • @Blam,是的或者那个。或锁定每一行。如上面的链接所述。
【解决方案2】:

使用模式切换,然后将所需的行拉入非备份表中

您需要创建一个包含相同元数据的表,但切换几乎是立即发生的。

CREATE TABLE dbo.Backup-Table1
(Col1 int
Col2 int)

ALTER TABLE dbo.Table1
SWITCH TO dbo.Backup-Table1

INSERT INTO dbo.Table1
SELECT TOP 100 *
FROM dbo.Backup-Table1
WHERE Condition = Met

【讨论】: