广告
返回顶部
首页 > 资讯 > 数据库 >Oracle中where条件执行顺序是什么
  • 566
分享到

Oracle中where条件执行顺序是什么

2024-04-02 19:04:59 566人浏览 薄情痞子
摘要

这篇文章将为大家详细讲解有关oracle中where条件执行顺序是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。问题:SYS@proc>

这篇文章将为大家详细讲解有关oracle中where条件执行顺序是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

问题:

  1. SYS@proc> create table t as select * from v$parameter;


  2. Table created.


  3. SYS@proc> select value from t where name='db_block_size' and to_number(value)=8192;


  4. VALUE

  5. --------------------------------------------------------------------------------

  6. 8192


  7. SYS@proc> select value from v$parameter where name='db_block_size' and to_number(value)=8192;

  8. select value from v$parameter where name='db_block_size' and to_number(value)=8192

  9.                                                              *

  10. ERROR at line 1:

  11. ORA-01722: invalid number

为什么语句“select value from t where name='db_block_size' and to_number(value)=8192;”执行成功,换成v$parameter却报错。

实验研究过程:

  1. SYS@proc> set autotrace on

  2. SYS@proc> analyze table t compute statistics;


  3. Table analyzed.


  4. SYS@proc> select value from t where name='db_block_size' and to_number(value)=8192;


  5. VALUE

  6. --------------------------------------------------------------------------------

  7. 8192



  8. Execution Plan

  9. ----------------------------------------------------------

  10. Plan hash value: 1601196873


  11. --------------------------------------------------------------------------

  12. | Id | Operation         | Name  | Rows | Bytes | Cost (%CPU)| Time     |

  13. --------------------------------------------------------------------------

  14. |  0 | SELECT STATEMENT  |       |    1 |    26 |       4 (0)| 00:00:01 |

  15. |* 1 |  TABLE ACCESS FULL| T     |    1 |    26 |       4 (0)| 00:00:01 |

  16. --------------------------------------------------------------------------


  17. Predicate InfORMation (identified by operation id):

  18. ---------------------------------------------------


  19.    1 - filter("NAME"='db_block_size' AND TO_NUMBER("VALUE")=8192)



  20. Statistics

  21. ----------------------------------------------------------

  22.       1  recursive calls

  23.       0  db block gets

  24.       9  consistent gets

  25.       0  physical reads

  26.       0  redo size

  27.    525  bytes sent via sql*Net to client

  28.    523  bytes received via SQL*Net from client

  29.       2  SQL*Net roundtrips to/from client

  30.       0  sorts (memory)

  31.       0  sorts (disk)

  32.       1 rows processed

一开始看到这个执行计划很懵逼,完全搞不懂为什么能够执行成功,做10046,10053,改写sql加hint还是搞不懂。
最后猜想Oracle在filter("NAME"='db_block_size' AND TO_NUMBER("VALUE")=8192)这个步骤,是先对数据做name='db_block_size'的过滤,在做to_number('value')=8192的过滤。
若是能将谓词信息改变成filter(TO_NUMBER("VALUE") AND  "NAME"='db_block_size'=8192)并且执行报错,那么猜想就是正确的。
尝试将sql语句的and条件调换位置"select value from t whereto_number(value)=8192  and  name='db_block_size';",不过还是和原来一样,这里省略步骤。

这里构造其他测试表:

  1. SYS@proc> create table a(id1 int,id2 int,id3 int,id4 int);


  2. Table created.


  3. SYS@proc> insert into a values(1,1,1,0);


  4. 1 row created.


  5. SYS@proc> commit;


  6. Commit complete.


  7. SYS@proc> select * from a;


  8.        ID1         ID2            ID3        ID4

  9. ---------- ---------- ---------- ----------

  10.          1             1                1           0

这里执行以下4条sql语句:
①Select 'ok' From aaa where id1/id2=1 and id3/id4=2;
②Select 'ok' From aaa where id1/id2=2 and id3/id4=2;
③Select 'ok' From aaa where id3/id4=2 and id1/id2=1;
④Select 'ok' From aaa where id3/id4=2 and id1/id2=2;
其中①和③,②和④只是where后条件位置互换而已。
查看执行结果:

  1. SYS@proc> Select 'ok' From aaa where id1/id2=1 and id3/id4=2;

  2. Select 'ok' From aaa where id1/id2=1 and id3/id4=2

  3.                                             *

  4. ERROR at line 1:

  5. ORA-01476: divisor is equal to zero



  6. SYS@proc> Select 'ok' From aaa where id1/id2=2 and id3/id4=2;


  7. no rows selected


  8. SYS@proc> Select 'ok' From aaa where id3/id4=2 and id1/id2=1;

  9. Select 'ok' From aaa where id3/id4=2 and id1/id2=1

  10.                               *

  11. ERROR at line 1:

  12. ORA-01476: divisor is equal to zero



  13. SYS@proc> Select 'ok' From aaa where id3/id4=2 and id1/id2=2;

  14. Select 'ok' From aaa where id3/id4=2 and id1/id2=2

  15.                               *

  16. ERROR at line 1:

  17. ORA-01476: divisor is equal to zero

②和④只是位置不同,但是一个却正常执行,一个却报错了。
这里查看两条sql的执行计划:

  1. SYS@proc> explain plan for Select 'ok' From aaa where id1/id2=2 and id3/id4=2;


  2. Explained.


  3. SYS@proc> select * from table(dbms_xplan.display());


  4. PLAN_TABLE_OUTPUT

  5. --------------------------------------------------------------------------------

  6. Plan hash value: 864433273


  7. -----------------------------------------------------------------------

  8. | Id | Operation         | Name | Rows | Bytes | Cost (%CPU)| Time     |

  9. ------------------------------------------------------------------------

  10. | 0  | SELECT STATEMENT  |      |    1 |    12 |     2   (0)| 00:00:01 |

  11. |* 1 |  TABLE ACCESS FULL| AAA  |    1 |    12 |     2   (0)| 00:00:01 |

  12. -----------------------------------------------------------------------


  13. Predicate Information (identified by operation id):

  14. ---------------------------------------------------


  15. PLAN_TABLE_OUTPUT

  16. --------------------------------------------------------------------------------


  17.    1 - filter("ID1"/"ID2"=2 AND "ID3"/"ID4"=2)


  18. 13 rows selected.


  19. SYS@proc> explain plan for Select 'ok' From aaa where id3/id4=2 and id1/id2=2;


  20. Explained.


  21. SYS@proc> select * from table(dbms_xplan.display());


  22. PLAN_TABLE_OUTPUT

  23. --------------------------------------------------------------------------------

  24. Plan hash value: 864433273


  25. ------------------------------------------------------------------------

  26. | Id | Operation         | Name | Rows | Bytes | Cost (%CPU)| Time     |

  27. ------------------------------------------------------------------------

  28. |  0 | SELECT STATEMENT  |      |    1 |    12 |     2   (0)| 00:00:01 |

  29. |* 1 |  TABLE ACCESS FULL|  AAA |    1 |    12 |     2   (0)| 00:00:01 |

  30. ------------------------------------------------------------------------


  31. Predicate Information (identified by operation id):

  32. ---------------------------------------------------


  33. PLAN_TABLE_OUTPUT

  34. --------------------------------------------------------------------------------


  35.    1 - filter("ID3"/"ID4"=2 AND "ID1"/"ID2"=2)


  36. 13 rows selected.

这里对比谓词信息刚好是两个位置不同,导致执行结果不一样。
正好说明上边的问题的猜想:
    最后猜想Oracle在filter("NAME"='db_block_size' AND TO_NUMBER("VALUE")=8192)这个步骤,是先对数据做name='db_block_size'的过滤,在做to_number('value')=8192的过滤。
    若是能将谓词信息改变成filter(TO_NUMBER("VALUE") AND  "NAME"='db_block_size'=8192)并且执行报错,那么猜想就是正确的。

由此问题解决。

其他:

  1. SYS@proc> create table test (id int);


  2. Table created.


  3. SYS@proc> insert into test values(null);


  4. 1 row created.

  5. SYS@proc> commit;


  6. Commit complete.


  7. SYS@proc> select * from test;


  8.     ID

  9. ----------



  10. SYS@proc> set autotrace on

  11. SYS@proc> select value from t,test a where a.id||name='db_block_size' and to_number(a.id||t.value)=8192;


  12. VALUE

  13. --------------------------------------------------------------------------------

  14. 8192



  15. Execution Plan

  16. ----------------------------------------------------------

  17. Plan hash value: 423998170


  18. ---------------------------------------------------------------------------

  19. | Id | Operation          | Name  | Rows | Bytes | Cost (%CPU)| Time     |

  20. ---------------------------------------------------------------------------

  21. |  0 | SELECT STATEMENT   |       |    1 |    39 |    6    (0)| 00:00:01 |

  22. |  1 |  NESTED LOOPS      |       |    1 |    39 |    6    (0)| 00:00:01 |

  23. |  2 |   TABLE ACCESS FULL| TEST  |    1 |    13 |    2    (0)| 00:00:01 |

  24. |* 3 |   TABLE ACCESS FULL| T     |    1 |    26 |    4    (0)| 00:00:01 |

  25. ---------------------------------------------------------------------------


  26. Predicate Information (identified by operation id):

  27. ---------------------------------------------------


  28.    3 - filter(TO_CHAR("A"."ID")||"NAME"='db_block_size' AND

  29.      TO_NUMBER(TO_CHAR("A"."ID")||"T"."VALUE")=8192)


  30. Note

  31. -----

  32.    - dynamic sampling used for this statement (level=2)



  33. Statistics

  34. ----------------------------------------------------------

  35.      32  recursive calls

  36.       0  db block gets

  37.      28  consistent gets

  38.       0  physical reads

  39.       0  redo size

  40.     525  bytes sent via SQL*Net to client

  41.     523  bytes received via SQL*Net from client

  42.       2  SQL*Net roundtrips to/from client

  43.       4  sorts (memory)

  44.       0  sorts (disk)

  45.       1 rows processed


  46. SYS@proc> set autotrace off

  47. SYS@proc> select value from t,test a where to_number(a.id||t.value)=8192 and a.id||name='db_block_size';

  48. select value from t,test a where to_number(a.id||t.value)=8192 and a.id||name='db_block_size'

  49.                                                 *

  50. ERROR at line 1:

  51. ORA-01722: invalid number



  52. SYS@proc> explain plan for select value from t,test a where to_number(a.id||t.value)=8192 and a.id||name='db_block_size';


  53. Explained.


  54. SYS@proc> select * from table(dbms_xplan.display());


  55. PLAN_TABLE_OUTPUT

  56. --------------------------------------------------------------------------------

  57. Plan hash value: 423998170


  58. ---------------------------------------------------------------------------

  59. | Id | Operation          | Name  | Rows | Bytes | Cost (%CPU)| Time     |

  60. ---------------------------------------------------------------------------

  61. |  0 | SELECT STATEMENT   |       |    1 |    39 |    6    (0)| 00:00:01 |

  62. |  1 |  NESTED LOOPS      |       |    1 |    39 |    6    (0)| 00:00:01 |

  63. |  2 |   TABLE ACCESS FULL| TEST   |    1 |    13 |    2    (0)| 00:00:01 |

  64. |* 3 |   TABLE ACCESS FULL| T     |    1 |    26 |    4    (0)| 00:00:01 |

  65. ---------------------------------------------------------------------------



  66. PLAN_TABLE_OUTPUT

  67. --------------------------------------------------------------------------------

  68. Predicate Information (identified by operation id):

  69. ---------------------------------------------------


  70.    3 - filter(TO_NUMBER(TO_CHAR("A"."ID")||"T"."VALUE")=8192 AND

  71.      TO_CHAR("A"."ID")||"NAME"='db_block_size')


  72. 16 rows selected.


所以where后边条件的执行顺序,实际上和执行计划谓词信息的顺序有关,和where的位置无关。
网上有些在10g做实验得出结论是从右到左,在11g里边,按照相同步骤执行并得不出相同结论。

问题延伸:
filter("NAME"='db_block_size' AND TO_NUMBER("VALUE")=8192),这里是一次性扫描出全部数据在进行过滤,还是一行一行获取在判断的。
延伸链接:Http://blog.itpub.net/30174570/viewspace-2149212/

关于Oracle中where条件执行顺序是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

您可能感兴趣的文档:

--结束END--

本文标题: Oracle中where条件执行顺序是什么

本文链接: https://www.lsjlt.com/news/65802.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Oracle中where条件执行顺序是什么
    这篇文章将为大家详细讲解有关Oracle中where条件执行顺序是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。问题:SYS@proc>...
    99+
    2022-10-19
  • where子句的执行顺序是什么
    本篇内容介绍了“where子句的执行顺序是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2022-10-18
  • join on和where执行顺序是什么
    这篇文章主要讲解了“join on和where执行顺序是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“join on和where执行顺序是什么”吧...
    99+
    2023-07-05
  • mysql中的join和where优先级顺序是什么
    这篇“mysql中的join和where优先级顺序是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“mysql中...
    99+
    2023-07-05
  • MySQL查询条件中on和where的区别是什么
    今天就跟大家聊聊有关MySQL查询条件中on和where的区别是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。MySQL 语句执行顺序...
    99+
    2022-10-18
  • mysql的执行顺序是什么
    mysql的执行顺序是什么?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1、执行顺序根据查询指定的表格,from计算笛卡尔积。on根据join_condition过滤数据。...
    99+
    2023-06-14
  • SQL语句中Where条件后写上1=1是什么意思
    这篇文章主要讲解了“SQL语句中Where条件后写上1=1是什么意思”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SQL语句中Where...
    99+
    2022-10-18
  • ​mysql中语句执行顺序是什么
    这篇文章给大家分享的是有关mysql中语句执行顺序是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。MySQL的语句一共分为11步,如下图所标注的那样,最先执行的总是FROM操...
    99+
    2022-10-18
  • oracle中where与having的区别是什么
    今天就跟大家聊聊有关oracle中where与having的区别是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1.wher...
    99+
    2022-10-18
  • MySQL 语句中 where 条件后为什么写上1=1 , 是什么意思?
    在 MySQL 中,where 条件是非常重要的,可以让我们筛选出所需的数据。在 SQL 语句中,where 条件通常会根据一定的条件过滤数据,例如查找年龄大于 18 岁的用户,语...
    99+
    2023-09-08
    mysql 数据库 sql
  • golang defer的执行顺序是什么
    在Go语言中,defer语句用于注册延迟调用,延迟调用会在函数执行完毕后被执行,无论函数是正常返回还是发生异常。 当有多个defer...
    99+
    2023-10-22
    golang
  • switch语句执行顺序是什么
    switch语句执行顺序是按照case标签的顺序进行判断,从上到下逐个比较。当找到与表达式匹配的case标签时,会执行该case标签...
    99+
    2023-09-16
    switch
  • sql和mysql执行顺序是什么
    这篇文章主要介绍了sql和mysql执行顺序是什么,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。sql和mysql执行顺序,内部机制是一样的,最...
    99+
    2022-10-18
  • Java中try-catch-finally执行顺序是什么
    本文小编为大家详细介绍“Java中try-catch-finally执行顺序是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java中try-catch-finally执行顺序是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入...
    99+
    2023-07-02
  • oracle中怎么查看sql执行计划的执行顺序
    这篇文章主要讲解了“oracle中怎么查看sql执行计划的执行顺序”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“oracle中怎么查看sql执行计划的执行顺...
    99+
    2022-10-18
  • java过滤器执行顺序是什么
    Java过滤器的执行顺序是根据过滤器的配置顺序来确定的。在web.xml文件中,过滤器的配置顺序决定了它们的执行顺序。当一个请求被发...
    99+
    2023-08-11
    java
  • SQL查询的执行顺序是什么
    本篇内容主要讲解“SQL查询的执行顺序是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SQL查询的执行顺序是什么”吧!很多 SQL 查询都是以 SELEC&...
    99+
    2022-10-19
  • JS异步的执行顺序是什么
    这篇文章主要介绍“JS异步的执行顺序是什么”,在日常操作中,相信很多人在JS异步的执行顺序是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JS异步的执行顺序是什么”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-07-02
  • PHP中for循环的执行顺序是什么
    本教程操作环境:windows7系统、PHP7.1版,DELL G3电脑for 循环是 PHP 中最复杂的循环结构。for 循环语句能够按照已知的循环次数进行循环操作,适用于明确知道执行次数的情况。for 循环的语法格式如下:for (初始...
    99+
    2016-02-26
    PHP for循环
  • C#类中方法的执行顺序是什么
    有些中级开发小伙伴还是搞不太明白在继承父类以及不同场景实例化的情况下,父类和子类的各种方法的执行顺序到底是什么,下面通过场景的举例来重新认识下方法的执行顺序: (下面内容涉及到了C#...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作