说我有这样的查询:
create table #Incident (id int)
insert into #Incident values (1)
SELECT INC_EVNT_URN,INC_CR_DTE FROM OPENQUERY(incidents,
'select * from incident')
Say事件中有8亿条记录,我只想得到其中一条记录。 #Incident存储在SQL Server表中。事件链接服务器是Oracle服务器。
我不能这样做:
select * from #Incident INNER JOIN (
SELECT ID FROM OPENQUERY(incidents,
'select * from incident')
) AS Incident ON #Incident.ID=Incidentid
我无法做到这一点的原因是因为它需要大约一天的时间才能运行,因为它首先从Oracle数据库中获取所有事件,然后才找到我需要的事件。有没有办法重构查询以提高效率?
答案 0 :(得分:1)
这实际上不是Oracle问题,而是SQL Server问题。 OPENQUERY
直接针对链接数据库运行第二个参数中标识的SQL脚本并返回结果。因此,“链接服务器”实际上是一种误称,因为您实际上只是在进行隔离数据库调用而不是在当前查询计划中引用外部对象。所以每次引用
OPENQUERY(incidents,'select * from incident')
您将该事件表的所有8亿条记录拉入缓存,然后针对该巨大临时表运行SQL Server查询。
为了避免这种情况,您将要缩小发送到Oracle Server的查询范围,以便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中进行,您只需要撤回所需的数据(而不是整个表)。