2014-01-24 30 views
0

我有兩臺服務器。一個是我的,另一個是另一個公司的。在第二臺服務器中,我不能創建任何數據庫或添加任何函數或存儲過程,但我需要返回信息以與數據庫交叉連接。與交叉連接的服務器連接

例如,

select fieldA, fieldB from localTBL l 
left join linkedserver.remoteDB.dboremoteTBL r on l.ID = r.ID 

select fieldA, fieldB from linkedserver.remoteDB.dboremoteTBL r 
where r.ID in (select l.ID from localTBL l) 

我這樣做,但表現得非常可怕。

是否有可能以更好的性能做到這一點?

回答

1

爲了提高鏈接服務器的性能,請使用openquery。否則,首先從遠程服務器返回所有數據,然後應用where子句。

在您的情況下,請首先運行子查詢,然後將值列表返回給變量。然後在你的openquery中使用這個變量。

+0

我大多同意使用OPENQUERY的情緒,但這不像黑白聲音。使用分佈式查詢(linkedserver.database.schema.table)**可以**首先返回所有數據,並在tempdb中創建一個副本(如果它認爲合適),然後應用過濾器。這個答案聽起來像它會一直這樣做。 – GarethD

+0

此外,分佈式查詢可以利用鏈接服務器上的統計信息,所以如果where子句意味着不會返回許多行,它將不會創建完整副本,並且會相應地調整任何進一步的交互(例如,可能會認爲嵌套循環連接比散列匹配更有效,因爲只有50行)。 OPENQUERY不能執行此操作,並且(AFAIK)始終假定將返回10,000行。這可能導致使用效率較低的連接回到其他數據。 – GarethD

0

是的。性能會很糟糕。這取決於您和其他公司之間的網絡,以及必須在途中完成的任何認證和授權。

這就是爲什麼鏈接服務器沒有被使用太多,即使是在一家公司內:性能通常很差。 (我從來沒有在一家獨立的公司看到鏈接服務器,並且只能同情!)

除非您可以升級您之間的網絡鏈接,否則沒有多少可以從鏈接服務器進行查詢。

這個設置聽起來像一個短期解決方案,需要一個快速修復的問題,並且持續時間比預期的要長。如果您可以獲得花錢的商業案例,有兩種選擇:

最便宜的替代方案是:將數據本地緩存:具有後臺服務正在運行,將最新版本的數據拖出鏈接服務器表在本地數據庫中設置一個表,然後針對本地表運行查詢。這取決於遠程數據的可變性以及查詢必須是最新的。外匯方面,如果您正在執行獲取昨天的銷售數據等事情,那麼您可能可以通宵通宵拉動。如果你需要更多的最新數據,也許每小時拉一次。你有時會變得相當挑剔,如果數據結構支持,它只會提取自上次拉動以來發生變化的數據:這使得每次拉動都變得更小,並允許更頻繁的拉動,也許......

更昂貴的涉及工作你和另一家公司:就是重新設計它,以便其他公司通過你公開的WCF服務(或者其他)推動你的變化。然後這可以在數據進入時更新您的本地副本。

1

CTE可用於僅通過線路提供所需的信息,然後針對呼叫服務器執行連接。就像:

DECLARE @Id As int; 
SELECT @Id = 45; 

with cte (ID, fieldB) 
AS 
(
    SELECT ID, fieldB 
    FROM linkedserver.remoteDB.dboremoteTBL 
    WHERE ID = @Id 
) 

SELECT lt.fieldA, cte.fieldB 
FROM localTbl lt 
    INNER JOIN cte ON lt.ID = cte.ID 
ORDER BY lt.ID;