Oracle数据库数据恢复、性能优化

找回密码
注册
搜索
热搜: 活动 交友 discuz
发新帖

13

积分

0

好友

1

主题
1#
发表于 2012-12-3 17:53:57 | 查看: 4269| 回复: 4
线上的一条SQL跑出的结果与预想的不一致。将问题简化,请大家帮忙看下。
问题描述:
SQL1为我期望得到的结果
SQL2为当前SQL写法,为什么条件and b.name = 'karl' 会导致
外连接转化为类似 access("A"."ID"="B"."ID")的等值连接?
最终导致结果集少了一条记录。

由于在MOS上未准确的定位到相类似的BUG,所以请大家帮忙解惑!
谢谢~



SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE        10.2.0.3.0        Production
TNS for HPUX: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production

SQL> select * from karl.tmp_a;

        ID
----------
         1
         2
SQL> select * from karl.tmp_b;

        ID NAME       SEX
---------- ---------- ----------
         1 karl      
            karlx      
         1            

--SQL1:这是我期望得到的两条结果
SQL> select a.id,b.* from tmp_a a left join tmp_b b on  a.id = b.id and b.name = 'karl';

        ID         ID NAME       SEX
---------- ---------- ---------- ----------
         1          1 karl      
         2   

Execution Plan
----------------------------------------------------------
Plan hash value: 3207854926

--------------------------------------------------------------------------------------
| Id  | Operation             | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |              |     2 |    80 |     6  (17)| 00:00:01 |
|*  1 |  HASH JOIN OUTER      |              |     2 |    80 |     6  (17)| 00:00:01 |
|   2 |   INDEX FAST FULL SCAN| SYS_C0021451 |     2 |    26 |     2   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL   | TMP_B        |     1 |    27 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("A"."ID"="B"."ID"(+))
   3 - filter("B"."NAME"(+)='karl')

--SQL2:这个是当前SQL的写法
SQL> select a.id,b.*
  2  from tmp_a a,tmp_b b
  3  where a.id =b.id(+)
  4  and b.name = 'karl' ;

        ID         ID NAME       SEX
---------- ---------- ---------- ----------
         1          1 karl   
--这里少了一条记录

Execution Plan
----------------------------------------------------------
Plan hash value: 1058953519

-----------------------------------------------------------------------------------
| Id  | Operation          | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |              |     1 |    40 |     3   (0)| 00:00:01 |
|   1 |  NESTED LOOPS      |              |     1 |    40 |     3   (0)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL| TMP_B        |     1 |    27 |     3   (0)| 00:00:01 |
|*  3 |   INDEX UNIQUE SCAN| SYS_C0021451 |     1 |    13 |     0   (0)| 00:00:01 |
-----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("B"."NAME"='karl')
   3 - access("A"."ID"="B"."ID")

5#
发表于 2012-12-3 23:13:30
我再考虑下这个问题怎么问,谢谢两位

回复 只看该作者 道具 举报

4#
发表于 2012-12-3 21:56:15
正在学SQL  好贴

回复 只看该作者 道具 举报

3#
发表于 2012-12-3 20:38:17
首先 贴代请用代码模式, 其次 你有必要了解下ORACLE SQL

  1. SQL> select * from tmp_a;

  2.         ID
  3. ----------
  4.          1
  5.          2

  6. SQL> select * from tmp_b;

  7.         ID NAME                 SEX
  8. ---------- -------------------- --------------------
  9.          1 karl
  10.            karlx
  11.          1


  12. SQL>  select a.id,b.* from tmp_a a left join tmp_b b on  a.id = b.id and b.name = 'karl';

  13.         ID         ID NAME                 SEX
  14. ---------- ---------- -------------------- --------------------
  15.          1          1 karl
  16.          2


  17. Execution Plan
  18. ----------------------------------------------------------
  19. Plan hash value: 399628481

  20. ----------------------------------------------------------------------------
  21. | Id  | Operation          | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
  22. ----------------------------------------------------------------------------
  23. |   0 | SELECT STATEMENT   |       |     2 |  4060 |     4   (0)| 00:00:01 |
  24. |*  1 |  HASH JOIN OUTER   |       |     2 |  4060 |     4   (0)| 00:00:01 |
  25. |   2 |   TABLE ACCESS FULL| TMP_A |     2 |    26 |     2   (0)| 00:00:01 |
  26. |*  3 |   TABLE ACCESS FULL| TMP_B |     1 |  2017 |     2   (0)| 00:00:01 |
  27. ----------------------------------------------------------------------------

  28. Predicate Information (identified by operation id):
  29. ---------------------------------------------------

  30.    1 - access("A"."ID"="B"."ID"(+))
  31.    3 - filter("B"."NAME"(+)='karl')
  32.    
  33.    
  34.    
  35. SQL> select a.id,b.*
  36.   2      from tmp_a a,tmp_b b
  37.   3      where a.id =b.id(+)
  38.   4      and b.name = 'karl' ;

  39.         ID         ID NAME                 SEX
  40. ---------- ---------- -------------------- --------------------
  41.          1          1 karl


  42. Execution Plan
  43. ----------------------------------------------------------
  44. Plan hash value: 202939653

  45. ----------------------------------------------------------------------------
  46. | Id  | Operation          | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
  47. ----------------------------------------------------------------------------
  48. |   0 | SELECT STATEMENT   |       |     1 |  2030 |     4   (0)| 00:00:01 |
  49. |*  1 |  HASH JOIN         |       |     1 |  2030 |     4   (0)| 00:00:01 |
  50. |*  2 |   TABLE ACCESS FULL| TMP_B |     1 |  2017 |     2   (0)| 00:00:01 |
  51. |   3 |   TABLE ACCESS FULL| TMP_A |     2 |    26 |     2   (0)| 00:00:01 |
  52. ----------------------------------------------------------------------------

  53. Predicate Information (identified by operation id):
  54. ---------------------------------------------------

  55.    1 - access("A"."ID"="B"."ID")
  56.    2 - filter("B"."NAME"='karl')

  57.    
  58.    
  59.    
  60.    SQL> select a.id,b.*
  61.         from tmp_a a,tmp_b b
  62.         where a.id =b.id(+)
  63.         and b.name(+) = 'karl' ;
  64.                
  65.                

  66. SQL> select a.id,b.*
  67.   2          from tmp_a a,tmp_b b
  68.   3          where a.id =b.id(+)
  69.   4          and b.name(+) = 'karl' ;

  70.         ID         ID NAME                 SEX
  71. ---------- ---------- -------------------- --------------------
  72.          1          1 karl
  73.          2


  74. Execution Plan
  75. ----------------------------------------------------------
  76. Plan hash value: 399628481

  77. ----------------------------------------------------------------------------
  78. | Id  | Operation          | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
  79. ----------------------------------------------------------------------------
  80. |   0 | SELECT STATEMENT   |       |     2 |  4060 |     4   (0)| 00:00:01 |
  81. |*  1 |  HASH JOIN OUTER   |       |     2 |  4060 |     4   (0)| 00:00:01 |
  82. |   2 |   TABLE ACCESS FULL| TMP_A |     2 |    26 |     2   (0)| 00:00:01 |
  83. |*  3 |   TABLE ACCESS FULL| TMP_B |     1 |  2017 |     2   (0)| 00:00:01 |
  84. ----------------------------------------------------------------------------

  85. Predicate Information (identified by operation id):
  86. ---------------------------------------------------

  87.    1 - access("A"."ID"="B"."ID"(+))
  88.    3 - filter("B"."NAME"(+)='karl')               
复制代码
和SQL1 等价的是 如下语句 ,不是你的SQL2
  1. select a.id,b.*
  2.     from tmp_a a,tmp_b b
  3.     where a.id =b.id(+)
  4.     and b.name(+) = 'karl' ;
复制代码

回复 只看该作者 道具 举报

2#
发表于 2012-12-3 18:10:22
本帖最后由 lianjie1229 于 2012-12-4 09:26 编辑

select a.id,b.*
   2  from tmp_a a,tmp_b b
   3  where a.id =b.id(+)
   4  and b.name(+) = 'karl' ;
b.name = 'karl'  在sql1中是连接条件,sql2中的写法是过滤条件,自动转换为内链接了,希望对你有帮助

回复 只看该作者 道具 举报

您需要登录后才可以回帖 登录 | 注册

QQ|手机版|Archiver|Oracle数据库数据恢复、性能优化

GMT+8, 2024-12-26 02:05 , Processed in 0.049690 second(s), 21 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部
TEL/電話+86 13764045638
Email service@parnassusdata.com
QQ 47079569