Oracle 缓慢地将本地 table 连接到 DB2 大型机
Oracle slow to join local table to DB2 Mainframe
这个让我很困惑。自己从 DB2 中拉取很快,从 table 中拉取也很快,但我不知道为什么它们不能很好地配合使用。我无权访问 DB2 table 或那里的服务器的索引。
此查询耗时 0.017 秒:
select
PART_NO,
APRV_DT,
round((CURRENT_DATE - APRV_DT)/365.242199,1) as AGE,
rank() over (partition by PART_NO order by APRV_DT asc) rnk,
FROM DB2_TABLE
where PART_NO in
('529711',
'627862',
'325712',
'979257',
'168570',
'004297')
显然我不想对所有零件号进行硬编码,因为我有将近 20 万个零件号要查询。
我在这里留下了部件号只是为了尝试让它工作。我 select 相同的 6 个零件号的查询需要 1.23 秒:
select distinct PART_NUMBER from PARTS_REPORT
where PART_NUMBER in
('529711',
'627862',
'325712',
'979257',
'168570',
'004297')
问题是当我将它们组合在一起时:
在我看来,此查询大约需要 3 秒左右。它需要 492 秒。
select
PART_NO,
APRV_DT,
round((CURRENT_DATE - APRV_DT)/365.242199,1) as AGE,
rank() over (partition by PART_NO order by APRV_DT asc) rnk,
FROM DB2_TABLE
where PART_NO in
(
select distinct PART_NUMBER from PARTS_REPORT
where PART_NUMBER in
('529711',
'627862',
'325712',
'979257',
'168570',
'004297')
)
有更好的方法吗?我需要索引我的 PARTS_REPORT table 吗?这里的关键是什么?
编辑:对于 运行 所有 200k 左右的零件号,相同的查询需要 564 秒 - 大约是我上面的 运行 所花费的时间。
编辑 2:下面的用户帮助我了解发生了什么 - 我必须拉下整个遥控器 table,这很慢。我想我明白现在发生了什么 - 谢谢。
总结我的评论作为答案:
在您的第一个查询中,您为查询提供了一个明确的 IN
列表,因此它在 DB2 服务器上完整地远程执行,从 DB2_TABLE
返回数据。
当您尝试从本地 table 检索搜索条件时(您使用 where PART_NO in
执行此操作),您会强制连接远程和本地 table,为此整个远程 table 必须发送到执行加入的本地服务器。
将本地 table(或其子集)发送到远程服务器以在那里执行加入可能需要更少的带宽。您可以通过声明一个临时 table、从 Oracle table 中加载部件号列表来实现这一点,然后对两个远程 table 执行查询,将连接本地化。
您已经在远程数据库中拥有一些权限,可以查询它的table(s);试试看你是否可以 运行 DECLARE GLOBAL TEMPORARY TABLE
-- 默认情况下它不需要任何超出正常 PUBLIC
权限的权限。
这个让我很困惑。自己从 DB2 中拉取很快,从 table 中拉取也很快,但我不知道为什么它们不能很好地配合使用。我无权访问 DB2 table 或那里的服务器的索引。
此查询耗时 0.017 秒:
select
PART_NO,
APRV_DT,
round((CURRENT_DATE - APRV_DT)/365.242199,1) as AGE,
rank() over (partition by PART_NO order by APRV_DT asc) rnk,
FROM DB2_TABLE
where PART_NO in
('529711',
'627862',
'325712',
'979257',
'168570',
'004297')
显然我不想对所有零件号进行硬编码,因为我有将近 20 万个零件号要查询。
我在这里留下了部件号只是为了尝试让它工作。我 select 相同的 6 个零件号的查询需要 1.23 秒:
select distinct PART_NUMBER from PARTS_REPORT
where PART_NUMBER in
('529711',
'627862',
'325712',
'979257',
'168570',
'004297')
问题是当我将它们组合在一起时:
在我看来,此查询大约需要 3 秒左右。它需要 492 秒。
select
PART_NO,
APRV_DT,
round((CURRENT_DATE - APRV_DT)/365.242199,1) as AGE,
rank() over (partition by PART_NO order by APRV_DT asc) rnk,
FROM DB2_TABLE
where PART_NO in
(
select distinct PART_NUMBER from PARTS_REPORT
where PART_NUMBER in
('529711',
'627862',
'325712',
'979257',
'168570',
'004297')
)
有更好的方法吗?我需要索引我的 PARTS_REPORT table 吗?这里的关键是什么?
编辑:对于 运行 所有 200k 左右的零件号,相同的查询需要 564 秒 - 大约是我上面的 运行 所花费的时间。
编辑 2:下面的用户帮助我了解发生了什么 - 我必须拉下整个遥控器 table,这很慢。我想我明白现在发生了什么 - 谢谢。
总结我的评论作为答案:
在您的第一个查询中,您为查询提供了一个明确的 IN
列表,因此它在 DB2 服务器上完整地远程执行,从 DB2_TABLE
返回数据。
当您尝试从本地 table 检索搜索条件时(您使用 where PART_NO in
执行此操作),您会强制连接远程和本地 table,为此整个远程 table 必须发送到执行加入的本地服务器。
将本地 table(或其子集)发送到远程服务器以在那里执行加入可能需要更少的带宽。您可以通过声明一个临时 table、从 Oracle table 中加载部件号列表来实现这一点,然后对两个远程 table 执行查询,将连接本地化。
您已经在远程数据库中拥有一些权限,可以查询它的table(s);试试看你是否可以 运行 DECLARE GLOBAL TEMPORARY TABLE
-- 默认情况下它不需要任何超出正常 PUBLIC
权限的权限。