Sql-Server

SQL Server 中具有連結伺服器的數據視圖的最佳實踐

  • March 8, 2016

在 SQL Server 中,我必須設計一個可以映射到 DBML 文件的視圖,以便從具有多個過濾條件的數據庫中動態檢索資訊。

問題是我必須組合來自多個表的資訊,其中一些在另一台伺服器上。

目前,我有一個包含大部分資訊的視圖,由伺服器 (A) 上多個表的多個連接組成,另一個伺服器 (B) 中的另一個視圖將伺服器 A 上的視圖與同一伺服器上的其他幾個表連接起來B.

因此,據我所知,數據的流動是這樣的: 伺服器 B 上的最終視圖 = 伺服器 A 視圖 JOIN 伺服器 B 表

這是伺服器 A 視圖的模板:

ALTER VIEW [dbo].[DataView_ServerA]
AS
SELECT     
   ss.Field, 
   ss.Field, 
   ss.Field, 
   ss.Field, 
   (CASE   WHEN ss.Field is null then 'Field not Assigned' else ss.Field end) as Field,
   mfl.Field as Field,
   St.Field,
   (CASE   WHEN ss.Field=0 THEN CAST(0 AS BIT)
           WHEN ss.Field=1 THEN CAST(1 AS BIT)
           else ss.Field end) as Field,

   fh.Field AS Field, 
   ssABC.Field AS Field,
   (CASE WHEN ssABCAB.Field IS NULL OR ssABC.Field IS NOT NULL THEN CAST(0 AS BIT) ELSE CAST(1 AS BIT) END) AS Field,
   (select (CASE WHEN count(Field)>=1 THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END) as treatedByAB from table where Field='Example' and id in (select Field from [table] where Field= fh.Field)) as Field

FROM         
   dbo.table AS ss WITH (nolock) 
LEFT OUTER JOIN
   dbo.table as St  WITH (nolock) on ss.Field!=St.Field
LEFT OUTER JOIN
   dbo.table AS ssABC WITH (nolock) ON ss.Field = ssABC.Field AND ssABC.Field = St.Field 
LEFT OUTER JOIN
   dbo.table AS fh WITH (nolock) ON fh.Field= ssABC.Field
LEFT OUTER JOIN
   dbo.table AS ssABCAB WITH (nolock) ON ss.Field= ssABCAB.FieldAND ssABCAB.Station = St.Station
LEFT OUTER JOIN
   dbo.table mfl ON ss.Field=mfl.Field and ss.Field=mfl.Fieldand ss.Field=mfl.Field and mfL.Field='Example'

伺服器 B 上最終視圖的模板是:

ALTER view [dbo].[FinalDataView_ServerB] as
select ABCraw.*, 
Tch.Field,
cat.Field,
f.Field


FROM [LinkedServer].[Database].[dbo].DataView_ServerA as raw

LEFT OUTER JOIN
   dbo.table AS f ON f.Field=raw.Field
LEFT OUTER JOIN
   dbo.table AS act ON f.Field = act.Field
LEFT OUTER JOIN
   dbo.table  AS cat ON f.Field = cat.Field
LEFT OUTER JOIN
   dbo.table AS Tch ON f.Field= Tch.Field

但是檢索寄存器的時間一般在7分鐘以上,數量上沒有區別。

您可以就如何重寫查詢以優化查詢或配置伺服器以更快地載入數據提供一些建議,我將不勝感激。

提前致謝。

以我的經驗,查詢的兩條腿上的循環連接肯定是一個昂貴的計劃。這取決於幾個問題,但請考慮使用這些選項來幫助您:

  1. 在伺服器 A 上使用名為**#DataTable_ServerB_local的臨時表或工作表**來儲存伺服器 B 的結果。
  2. 如果可能,在伺服器 B 上創建一個儲存過程Prepare_Datatable_ServerB_Data,您可以遠端呼叫該儲存過程來獲取伺服器 B 數據。這可能會加入回伺服器 A 以獲取一些數據。
  3. 用於OPENQUERY執行遠端儲存過程Prepare_Datatable_ServerB_Data 以將其數據插入伺服器 A 的**#DataTable_ServerB_local**。儲存過程內部的程式碼將連接回本地伺服器,以獲取我懷疑它需要的相對較少的行
  4. 將DataView_ServerA與#DataTable_ServerB_local連接起來,它們現在都在伺服器 A上以提供最終結果。

此策略假設伺服器 B 加入回伺服器 A 是較小的連接集。(如果不是這種情況,那麼您將需要使用此策略切換方向。)

這種方法的重點是:

  1. 限制伺服器之間傳遞的行數。
  2. 盡可能避免跨連結伺服器的連接。
  3. 盡可能(例如Prepare_Datatable_ServerB_Data過程)在儲存數據的伺服器上處理數據。

跨連結伺服器的大連接在時間方面可能非常昂貴,並且優化器可能無法做出正確的決策。

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