Sql-Server

在兩個表之間同步索引

  • May 8, 2020

我需要在同一個數據庫中的兩個表(Primary 和 Stage_Table)之間自動化和同步索引。

我嘗試使用 SSIS SQL Server 對象任務,但看起來它僅在我們在兩個不同實例之間同步時才有效。主表上的索引不斷變化,當我進行分區切換時,我需要帶有所有更新索引的空 stage_table。

您可以使用開源工具,如sql-dbdiffOpenDBDiff。兩者都是命令行,因此可用於自動化腳本。

此外,如果您想要第 3 方許可的工具,那麼 Redgate 的SQL 比較(如果您想要進行數據比較——也有數據比較)非常有用,我已經將它廣泛用於自動化。

出於好奇,為什麼需要 Staging table 上的索引,因為 staging table 是為了臨時載入數據,然後在清理它之後,將數據載入到主表中?

編輯 :

根據您的需要,最好使用Codeplex 的SQL Server 分區管理工具

該實用程序提供了一個命令行界面,用於: 1. 通過將一個分區切換到一個臨時表來刪除該分區中的所有數據。它創建所需的登台table.2。創建臨時表以將數據載入到分區中。可以使用或不使用索引來創建臨時表——如果創建時不使用索引,此實用程序會提供一個單獨的命令來在臨時表上創建適當的索引,然後再將其切換到分區表中。可以從其他腳本呼叫這些命令以實現端到端滑動視窗場景。使用該實用程序可以避免維護必須與永久表中的索引或列更改保持同步的分區維護腳本,因為可以按需創建必要的暫存對象。

另一種選擇是DDL 觸發器,它可以擷取索引操作

USE your_database;
GO

CREATE TRIGGER [IndexEventAudit]
  ON DATABASE
  FOR ALTER_INDEX, CREATE_INDEX, DROP_INDEX
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @e XML = EVENTDATA();

  DECLARE @sql NVARCHAR(MAX) 
    = @e.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(MAX)');

  DECLARE @obj SYSNAME 
    = @e.value('(/EVENT_INSTANCE/TargetObjectName)[1]', 'nvarchar(128)')

  IF @obj = N'Primary_Table'
  BEGIN
    SET @sql = REPLACE(@sql, N'Primary_Table', N'Stage_Table');
    EXEC sp_executesql @sql;
  END
END
GO

這裡有一個狹窄的失敗案例;如果您在嵌入了表名的列上有索引。例如,這將失敗:

CREATE INDEX foo ON dbo.Primary_Table(Primary_Table_id);

因為替換的 SQL 看起來像這樣:

CREATE INDEX foo ON dbo.Stage_Table(Stage_Table_id);
-------- wrong column name ---------^^^^^^^^^^^^^^

您可能還想添加預防措施以確保其他人不會嘗試stage_table直接更改索引,這顯然會與這種方法(以及其他方法,也可能)混淆。另請注意,您可能需要擴展它以擷取諸如約束之類的內容,並且如果主表的架構更改未反映在輔助表中,或者如果您有命名衝突等,您將需要以某種方式處理這些。例如,有人可以向主表添加一列,然後對其進行索引,而輔助表上的索引將失敗,因為列更改沒有反映在那裡。

引用自:https://dba.stackexchange.com/questions/41282