2016-03-01 66 views
0

說我有這樣的查詢:Oracle鏈接服務器太慢

create table #Incident (id int) 
insert into #Incident values (1) 

    SELECT INC_EVNT_URN,INC_CR_DTE FROM OPENQUERY(incidents, 
    'select * from incident') 

說事件有800萬條記錄在裏面,我只想讓他們的一個。 #Incident存儲在SQL Server表中。事件鏈接服務器是一個Oracle服務器。

我不能做到這一點:

select * from #Incident INNER JOIN (
SELECT ID FROM OPENQUERY(incidents, 
'select * from incident') 
) AS Incident ON #Incident.ID=Incidentid 

我不能這樣做的原因是因爲它需要大約一天運行,因爲它首先獲取所有從Oracle數據庫中的事件發現,我需要一個之前。有沒有一種方法來重構查詢,使其更有效率?

回答

1

這實際上不是一個SQL Server少一個Oracle問題。 OPENQUERY直接針對鏈接數據庫運行第二個參數中標識的SQL腳本並返回結果。因此,「鏈接服務器」真的是那種一個用詞不當,因爲你真的只是做一個孤立的數據庫調用,而不是引用在當前的查詢計劃異物。所以每次你參考

OPENQUERY(incidents,'select * from incident') 

你拉在所有8億條記錄這一事件表到高速緩存中,然後運行鍼對巨大的臨時表的SQL Server查詢。

爲了避免這種情況,你會想縮小您發送到Oracle服務器的查詢,以便Oracle解析器可以運行一個更清潔的計劃。看看這個link描述變量傳遞到OPENQUERY

通基本價值觀

當基本Transact-SQL語句是已知的,但你必須在一個或多個特定值,使用代碼是類似於 通過 下面的示例:

DECLARE @TSQL varchar(8000), @VAR char(2) 
     SELECT @VAR = 'CA' 
     SELECT @TSQL = 'SELECT * FROM OPENQUERY(MyLinkedServer,''SELECT * FROM pubs.dbo.authors WHERE state = ''''' + @VAR + ''''''')' 
     EXEC (@TSQL) 

利用這些信息,我會嘗試通過在案發ID你正在尋找。然後,所有的工作都在Oracle中進行,您只需要撤回所需的數據(而不是整個表)。