gpt4 book ai didi

sql - 分布式查询是否禁用绑定(bind)窥视?

转载 作者:行者123 更新时间:2023-12-04 08:52:55 25 4
gpt4 key购买 nike

在升级到 Oracle 11g 后,我在优化 Oracle 查询时遇到了问题,这个问题开始让我有点抓狂。

注意,这个问题现在已经被完全编辑过了,因为在创建一个简单的测试用例后我有更多的信息。原始问题可在此处获得:https://stackoverflow.com/revisions/12304320/1 .

这个问题是当连接两个表时,其中一个表有 between日期列上的条件,如果查询连接到远程表,则不会发生绑定(bind)偷看。

这是一个帮助重现问题的测试用例。首先设置两个源表。第一个是日期列表,是本月的第一天,可以追溯到三十年前

create table mike_temp_etl_control
as
select
add_months(trunc(sysdate, 'MM'), 1-row_count) as reporting_date
from (
select level as row_count
from dual
connect by level < 360
);

然后一些数据来自 dba_objects :
create table mike_temp_dba_objects as
select owner, object_name, subobject_name, object_id, created
from dba_objects
union all
select owner, object_name, subobject_name, object_id, created
from dba_objects;

然后创建一个空表来运行数据:
create table mike_temp_1
as
select
a.OWNER,
a.OBJECT_NAME,
a.SUBOBJECT_NAME,
a.OBJECT_ID,
a.CREATED,
b.REPORTING_DATE
from
mike_temp_dba_objects a
join mike_temp_etl_control b on (
b.reporting_date between add_months(a.created, -24) and a.created)
where 1=2;

然后运行代码。您可能需要创建一个更大的版本 mike_temp_dba_objects 以减慢查询速度(或使用其他方法来获取执行计划)。在查询运行时,我通过运行 select *
from table(dbms_xplan.display_cursor(sql_id => 'xxxxxxxxxxx'))
从 session 中获取执行计划来自不同的 session 。
declare
pv_report_start_date date := date '2002-01-01';
v_report_end_date date := date '2012-07-01';

begin

INSERT /*+ APPEND */
INTO mike_temp_5
select
a.OWNER,
a.OBJECT_NAME,
a.SUBOBJECT_NAME,
a.OBJECT_ID,
a.CREATED,
b.REPORTING_DATE
from
mike_temp_dba_objects a
join mike_temp_etl_control b on (
b.reporting_date between add_months(a.created, -24) and a.created)
cross join dual@emirrl -- This line causes problems...
where
b.reporting_date between add_months(pv_report_start_date, -12) and v_report_end_date;

rollback;
end;

通过在查询中有一个远程表,mike_temp_etl_control 表的基数估计是完全错误的,并且绑定(bind)偷看似乎没有发生。

上面查询的执行计划如下所示:
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
---------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | | | 373 (100)|
| 1 | LOAD AS SELECT | | | | |
|* 2 | FILTER | | | | |
| 3 | MERGE JOIN | | 5 | 655 | 373 (21)|
| 4 | SORT JOIN | | 1096 | 130K| 370 (20)|
| 5 | MERGE JOIN CARTESIAN| | 1096 | 130K| 369 (20)|
| 6 | REMOTE | DUAL | 1 | | 2 (0)|
| 7 | BUFFER SORT | | 1096 | 130K| 367 (20)|
|* 8 | TABLE ACCESS FULL | MIKE_TEMP_DBA_OBJECTS | 1096 | 130K| 367 (20)|
|* 9 | FILTER | | | | |
|* 10 | SORT JOIN | | 2 | 18 | 3 (34)|
|* 11 | TABLE ACCESS FULL | MIKE_TEMP_ETL_CONTROL | 2 | 18 | 2 (0)|
---------------------------------------------------------------------------------------

如果我再更换 Remote dual使用本地版本,我得到了正确的基数(139 而不是 2):
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
-------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | | | 10682 (100)|
| 1 | LOAD AS SELECT | | | | |
|* 2 | FILTER | | | | |
| 3 | MERGE JOIN | | 152K| 19M| 10682 (3)|
| 4 | SORT JOIN | | 438K| 51M| 10632 (2)|
| 5 | NESTED LOOPS | | 438K| 51M| 369 (20)|
| 6 | FAST DUAL | | 1 | | 2 (0)|
|* 7 | TABLE ACCESS FULL| MIKE_TEMP_DBA_OBJECTS | 438K| 51M| 367 (20)|
|* 8 | FILTER | | | | |
|* 9 | SORT JOIN | | 139 | 1251 | 3 (34)|
|* 10 | TABLE ACCESS FULL| MIKE_TEMP_ETL_CONTROL | 139 | 1251 | 2 (0)|
-------------------------------------------------------------------------------------

所以,我想问题是我怎样才能得到正确的基数来估计?这是 Oracle 错误还是预期的行为?

最佳答案

我认为你应该搞砸动态采样。它在 11g 中的工作方式不同,因此可能是您遇到麻烦的原因。

关于sql - 分布式查询是否禁用绑定(bind)窥视?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12304320/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com