0

在有所有第三方一套表和DB是好的....然後開始......將多個重複EXISTS語句是在多個加盟的觀點在SQL Server中得到優化

之一我們的第三方需要公開他們的一些數據,以便隱藏所有其他客戶數據解決方案,以創建另一組表(!!!),其中我們將爲該第三方複製數據並僅將訪問權授予其鏡像集表....直到另一個第三方要求相同...然後另一個....然後我進來...

自動櫃員機我想引入一組Views每個第三方坐在他們自己的第三方Schema並從原始表中進行子選擇...在新Views中標識哪些記錄顯示給我計劃介紹RecordOwner表的人員。在那裏我需要在特定視圖集中顯示需要顯示記錄的PK和所有者列。 (其他選項將添加到'主'表,持有PK添加所有者列,並從那裏確定所有者......但我認爲這不太靈活...)

我的看法看起來像這樣名稱僅用於說明):

CREATE VIEW [3rdPartyTable] 
AS 
    SELECT * 
    FROM [OriginalTable] ot 
    WHERE EXISTS (SELECT 1 FROM [RecordOwner] 
       WHERE [Id] = ot.[Id] AND [Owner] = 'Owner1') 

CREATE VIEW [3rdPartyTable2] 
AS 
    SELECT * 
    FROM [OriginalTable2] ot 
    WHERE EXISTS (SELECT 1 FROM [RecordOwner] 
        WHERE [Id] = ot.[MasterId] AND [Owner] = 'Owner1') 

我在考慮性能,因爲在那些原始表中有相當多的幾百萬條記錄。當每個第三方將運行他們的查詢,並會加入他們的意見,將SQL服務器是足夠聰明的優化多個相同的重複

where exists (select 1 from [RecordOwner] 
       where [Id] = ot.[MasterId] and [Owner] = 'Owner1') 

與否?

編輯:考慮下面的查詢第三方開發寫道:

SELECT * from [3rdPartyTable2] t2 
inner join [3rdPartyTable3] t3 on t2.MasterId = t3.Masterid 

這然後將轉化

SELECT * FROM 
    (SELECT * FROM [OriginalTable2] ot 
    where exists (select 1 from [RecordOwner] where [Id] = ot.[MasterId] and [Owner] = 'Owner1')) t2 
inner join 
    (SELECT * FROM [OriginalTable3] ot 
    where exists (select 1 from [RecordOwner] where [Id] = ot.[MasterId] and [Owner] = 'Owner1')) t3 
on t2.MasterId = t3.Masterid 

和兩個表具有PK上MasterId

SQL Server是否足夠聰明,可以優化視圖中多個重複的EXISTS子句?

+0

我假設'Id' /'MasterId'是一個GUID而不是身份字段?!否則,你會碰到重疊。無論如何,如果「RecordOwner」的PK是「Owner」和「MasterId」,那麼爲什麼不簡單地使用'JOIN'而不是'WHERE EXISTS()'?在每種情況下,我都很困惑,爲什麼你會期望服務器神奇地將這些不同的鏈接「合併」到「RecordOwner」表中? 「ot2」的值與「ot3」的值沒有什麼共同之處......也就是說,我不會擔心性能太高,爲每個客戶端保留這些表的副本將花費更多的精力和資源。 – deroby

回答

0

TL; DR;使用JOINS構建的視圖與使用EXISTS構建的視圖(並且它們在LEFT OUTER JOINS上得到優化)相同或更快。

就像@戈登答案的確認一樣,我做了實驗,做了視圖,索引並填充了數據庫中93%的PK記錄數據,從執行計劃中可以看出,當連接3個表時,它執行了3次掃描。 ..

enter image description here

開銷(〜每加入3%)是最小的,但...

編輯:於LEFT OUTER JOIN加盟的看法時冉另一組的測試和執行計劃是相同的,但當做INNER JOINS查看正在使用JOIN而不是EXISTS跑贏後者構造小號...的視圖與

例JOIN:視

CREATE VIEW [dbo].[Summary2] 
AS 
SELECT st.* 
    FROM [OriginalSummary] st 
    inner join [RecordOwner] ro on ro.[Id] = st.[MasterId] and [Owner] = 'corp1' 

enter image description here

實施例與EXISTS:

CREATE VIEW [dbo].[Summary] 
AS 
SELECT * 
FROM [OriginalSummary] ot 
WHERE EXISTS (SELECT 1 FROM [RecordOwner] 
       WHERE [Id] = ot.[MasterId] AND [Owner] = 'corp1') 
GO 

enter image description here

0

這太長了評論。

你在說什麼?您的exists表達式正在使用相關的子查詢。因此,每個查詢都是一個獨立且不同的查詢,因爲它們引用外部查詢中的不同表。

隨着RecordOwner(Id, Owner)上的索引,性能應該沒問題。但是,你應該測試它。

您也可以考慮爲每個客戶端單獨編寫一個視圖。客戶可能會更舒適地訪問所謂的table_client,而不是依賴於隱藏的安全機制。

+0

喜登,想象第三方寫入選擇'選擇[3rdPartyTable2] T2 內加入[3rdPartyTable3]上t2.MasterId T3 = t3.Masterid' 這然後將轉化 '(SELECT * FROM [OriginalTable2 * ] ot where exists(從[RecordOwner]中選擇1,其中[Id] = ot。[MasterId]和[Owner] ='Owner1')) 內部連接(SELECT * FROM [OriginalTable3] ot where exists(select 1從[RecordOwner]其中[Id] = ot。[MasterId]和[Owner] ='Owner1'))'兩個表在主記錄 –

+0

@MatasVaitkevicius上都有PK。 。 。我嚴重懷疑SQL Server或任何其他數據庫會優化掉其中一個「exists」。 –