现有oracle 11g r2 安装在A服务器和B服务器上,分别为 A数据库和B数据库。
且A、B 数据库 都有表 ctltmp.wrs_dhhm1(1万数据量)、ctltmp.tb_ms_trading_stamps(22万数据量)。-- 在A数据库执行下面sql,要180多秒才能出结果
SELECT t2.*
From ctltmp.wrs_dhhm1 t1, ctltmp.tb_ms_trading_stamps@B t2
WHERE t1.bm = t2.stamps_code;
-- 执行计划如下:-- 在B数据库执行同样的sql,2秒就能出结果
SELECT t2.*
From ctltmp.wrs_dhhm1 t1, ctltmp.tb_ms_trading_stamps@A t2
WHERE t1.bm = t2.stamps_code;
-- 执行计划如下:
为什么两台数据库之间A通过dblink关联B的表这么慢,而B通过dblink关联A这么快呢?执行计划是一样的。
如果是网络的问题的话,两个不是应该都慢的吗?-- 再做一个测试如下,在A服务器上加hint,执行sql,2秒就出结果
SELECT /*+driving_site(t2)*/t2.*
From ctltmp.wrs_dhhm1 t1, ctltmp.tb_ms_trading_stamps@B t2
WHERE t1.bm = t2.stamps_code;
-- 执行计划如下:
问题:为什么oracle不默认选择这种速度较快的查询计划呢?这个问题困扰我很久了,问了很多人,发了很多帖都没解决,麻烦各位大神牛人帮忙看看,走过路过的帮忙顶下!
谢谢!
且A、B 数据库 都有表 ctltmp.wrs_dhhm1(1万数据量)、ctltmp.tb_ms_trading_stamps(22万数据量)。-- 在A数据库执行下面sql,要180多秒才能出结果
SELECT t2.*
From ctltmp.wrs_dhhm1 t1, ctltmp.tb_ms_trading_stamps@B t2
WHERE t1.bm = t2.stamps_code;
-- 执行计划如下:-- 在B数据库执行同样的sql,2秒就能出结果
SELECT t2.*
From ctltmp.wrs_dhhm1 t1, ctltmp.tb_ms_trading_stamps@A t2
WHERE t1.bm = t2.stamps_code;
-- 执行计划如下:
为什么两台数据库之间A通过dblink关联B的表这么慢,而B通过dblink关联A这么快呢?执行计划是一样的。
如果是网络的问题的话,两个不是应该都慢的吗?-- 再做一个测试如下,在A服务器上加hint,执行sql,2秒就出结果
SELECT /*+driving_site(t2)*/t2.*
From ctltmp.wrs_dhhm1 t1, ctltmp.tb_ms_trading_stamps@B t2
WHERE t1.bm = t2.stamps_code;
-- 执行计划如下:
问题:为什么oracle不默认选择这种速度较快的查询计划呢?这个问题困扰我很久了,问了很多人,发了很多帖都没解决,麻烦各位大神牛人帮忙看看,走过路过的帮忙顶下!
谢谢!
SELECT b.*
From ctltmp.wrs_dhhm1 a, ctltmp.tb_ms_trading_stamps@B b
WHERE a.bm = b.stamps_codecall count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.02 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 2.07 165.38 0 37 0 100
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 2.07 165.41 0 37 0 100Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 87 Rows Row Source Operation
------- ---------------------------------------------------
100 HASH JOIN (cr=37 pr=0 pw=0 time=12147993 us cost=925 size=6806015 card=18545)
10000 TABLE ACCESS FULL WRS_DHHM1 (cr=37 pr=0 pw=0 time=1898 us cost=12 size=190000 card=10000)
26951 REMOTE TB_MS_TRADING_STAMPS (cr=0 pr=0 pw=0 time=2351164 us cost=910 size=145477572 card=418039)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
SQL*Net message from client 2 0.02 0.04
SQL*Net message to dblink 13476 0.00 0.01
SQL*Net message from dblink 13476 0.02 163.67
SQL*Net more data to client 1 0.00 0.00
如果stamps_code的选择性较好,可以建索引试试看。
你试试看,只是
A站:select * from ctltmp.tb_ms_trading_stamps@B;
B站:select * from ctltmp.tb_ms_trading_stamps@A;
比较下结果?
Rows Row Source Operation
------- ---------------------------------------------------
100 HASH JOIN (cr=37 pr=0 pw=0 time=12147993 us cost=925 size=6806015 card=18545)
10000 TABLE ACCESS FULL WRS_DHHM1 (cr=37 pr=0 pw=0 time=1898 us cost=12 size=190000 card=10000)
26951 REMOTE TB_MS_TRADING_STAMPS (cr=0 pr=0 pw=0 time=2351164 us cost=910 size=145477572 card=418039)--我认为是这个评估有问题Rows Row Source Operation
26951 REMOTE TB_MS_TRADING_STAMPS (cr=0 pr=0 pw=0 time=2351164 us cost=910 size=145477572 card=418039)
--明显TB_MS_TRADING_STAMPS只有22万数据量,但是card=418039,导致DBLINK读取的数据多了一倍,因此性能变差了,这个是CBO的问题,感觉好像是没有获取到正确的统计信息
A库:select * from ctltmp.tb_ms_trading_stamps@B where rownum<=50;
B库:select * from ctltmp.tb_ms_trading_stamps@A where rownum<=50;
这样两条执行时间基本都稳定 0.2秒-0.3秒。
加了rownum 是不是意味着 oracle不会去读统计信息,直接返回前50条数据,所以查询就变稳定了呢?