- 浏览: 90700 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (81)
- 读书笔记 (14)
- NetBeans学习 (1)
- JavaBeans and Bean Events (3)
- 《Pro Oracle SQL》Chapter 2 SQL Execution (13)
- 《Pro Oracle SQL》Chapter 3 Access and Join Methods (16)
- Pro Oracle SQL Chapter 5 (0)
- Pro Oracle SQL Chapter 6 (0)
- Pro Oracle SQL Chapter 7 (9)
- Pro Oracle SQL Chapter 8 (9)
- 《Pro Oracle SQL》Chapter 9 The Model Clause (11)
- 《Pro Oracle SQL》Chapter 10 Subquery Factoring (7)
最新评论
-
mojunbin:
这个不能不顶。
《Pro Oracle SQL》 Chapter2--2.1 Oracle Architecture Basics -
Branding:
谢谢,获益匪浅
《Pro Oracle SQL》--chapter 5--5.6 Building Logical Expressions -
Branding:
《Pro Oracle SQL》--Chapter 5--5.4 Questions about the Question -
Branding:
谢谢
《Pro Oracle SQL》 翻译序 -- 读书心得 -
jiaoshiguoke:
继续 加油
《Pro Oracle SQL》--Chapter 6--6.1 Explain Plans--之三
《Pro Oracle SQL》--chapter 5--5.6 Building Logical Expressions
- 博客分类:
- 读书笔记
5.6 Building Logical Expresions 构建逻辑表达式 (page 140)
Once you understand the question that the statement you are writing needs to answer, you have to be able to build the SQL to provide the answer. There are often many possible ways to express the same predicate logic. Being able to formulate the conditions in a way that is easy to read and efficient requires you to think in ways you may not be used to. Remember when I discussed the idea of thinking in sets versus thinking procedurally in Chapter 4? There is a similar thought-shift that you may need to make in order to be able to build predicates for your SQL statements most efficiently.
当你理解了所写语句前需要解答的问题时,你必须通过写SQL来找出答案。有许多可行的方案表示同样的谓词逻辑(predicate logic)。为了能用易读且有效的方式公式化表示条件,你可能要用非同一般的方法思考。还记得我在第四章所讨论的用集合的方式思考而不是用过程的方式思考么?这里类似你也要做一次思维转移,来构建谓词让你的SQL语句更有效率。
The key is to learn some good Boolean logic techniques so that you don’t have to rely on only one
way to express conditional logic. You may find that using Boolean logic expressions will always produce the most efficient plan operation choices (make sure to test alternatives thoroughly), but it’s good to know how to formulate different alternatives so you aren’t stuck with a single way to do things.
关键是要学会一些好的布尔逻辑技术,让你不只是依赖于一种方式表达条件逻辑。你将发现使用布尔逻辑表达式总能产生最有效率的运算选择计划(确保一定彻底的测试替代方案)。知道(数据库)如何公式化表示不同的方案对你是有益的,这让你不会拘泥于只用一种方法做事情。
When I say conditional logic, I mean an expression something like “if X then Y” where X and Y are
both conditions. In a WHERE clause, you might want to have a condition like if :GetAll <> 1 then empno = :empno. In other words, if the value of the input bind variable named :GetAll is 1, then you want to return all rows, but if :GetAll is not 1, then only return rows where empno is equal to the :empno bind variable supplied. A WHERE clause to express this logic might be coded like this:
WHERE empno = CASE WHEN :GetAll <> 1 THEN :empno ELSE empno END
当我说条件逻辑,我的意思是某个像“if X then Y” 的表达式,其中X和Y都是条件。在Where子句中,你可能想要一个像这样的条件,
if:GetAll <> 1 then empno = :empno
。换句话说,如果名为:GetAll的绑定变量的值为1,你就要返回所有的行。但是如果:GetAll不是1,就仅仅返回empno等于绑定变
量:empno所指定的那一行。表示这个逻辑的Where子句的代码可能这样写:
WHERE empno = CASE WHEN :GetAll <> 1 THEN :empno ELSE empno END
This logic works, but is a bit counterintuitive to me. Why would you even want to check empno =
empno? There are other problems with this kind of formulation as well. If you need to check multiple
columns, then you’ll need multiple CASE statements. Plus, if empno is null, this check will fail, or at the
very least give you a result you didn’t expect.
这个逻辑是对的,但是我感觉不直观。你为什么要去检查empno=empno?还有另外的问题,如果你需要检查多列,你就需要多个CASE语句。甚者,如果empno是空,这个检查将失败,或者至少给你不期望的结果。
The key is to change this expression to use a regular Boolean expression that uses only AND, OR, and NOT so that your “if X then Y” condition is translated to “(Not X) or Y”. This becomes:
WHERE (:GetAll = 1) OR (empno = :empno)
改造这个表达式的关键是使用正规的布尔表达式,仅仅使用AND,OR和NOT。这样你的“if X then Y”就可以翻译成“(Not X) or Y”。这就成了:
WHERE (:GetAll = 1) OR (empno = :empno)
What you are covering with this expression is that if :GetAll = 1, then you don’t even want to
bother with checking any more of the expression. Always remember that when using an OR condition, if one condition evaluates to TRUE, then the whole expression is TRUE. There is no need to even check the remaining expression. This “short-circuit” mechanism can save time by not requiring some of the code path to be evaluated. That means you’ll not burn as many CPU cycles over all. Only if the first condition that the optimizer chooses to test evaluates to FALSE would the other expression need to be evaluated.
你用表达式if:GetAll = 1去覆盖,
然后你不希望更麻烦的去检查其他的表达式。永远记住当使用OR条件,如果一个条件评估成真,这个表达式为真。没有必要再去检查其他的表达式。这个“短路”
机制,不需要评估一些代码路径,而节约时间。这意味着你完全可以让CPU少运转。只有优化器选择的第一个条件评估为FALSE才需要去评估其它的表达式。
Although you’re not looking at expressions involving ANDed conditions in these examples, you can
apply similar thinking to the use of ANDed predicates. When using an AND condition, if the first condition evaluates to FALSE, then the whole expression is FALSE. There is no need to evaluate the second expression since both conditions must evaluate to TRUE for the whole condition to be TRUE. So, when you’re using AND conditions, it’s a good idea to write the condition so the expression that is most likely to evaluate to FALSE is placed first. Doing so allows the second expression evaluation to be short-circuited with similar savings as noted when placing a TRUE expression first in an OR condition.
尽管在这个例子中没有讨论涉及AND的条件表达式,你能应用相似的思维于AND谓词。当使用AND,如果第一个条件评估成FALSE,整个表达式是
FALSE。没有必要去评估第二个表达式,因为两个条件都为TRUE时,整个表达式才是TRUE。如果你用AND条件,将最有可能评估是FALSE的表达
式写在(整个表达式)最前面是个聪明的注意。这样做将允许第二个表达式被“短路”,类似于将TRUE表达式放在OR条件之前能节约时间。
A similar way of approaching this type of conditional expression is to use a single bind variable
instead of two. In this case, you could say “if X is not null then Y = X”. This becomes:
WHERE empno = NVL(:empno, empno)
This is basically the same as writing the CASE expression from the earlier example and could be
converted to:
WHERE (:empno is null) OR (empno = :empno)
一种类似的方法完成这种条件表达式是使用单个绑定变量而非两个。在这个例子中,你可以说成是:“if X is not null then Y=X”。这就成了:
WHERE empno = NVL(:empno, empno)
本质上同前面写的CASE表达式是一样的,也可以转成:
WHERE (:empno is null) OR (empno = :empno)
In both of these cases, the optimizer may have a bit of a dilemma with determining the optimal
plan. The reason is that if the binds you use cause the comparison to end up returning all rows, then the plan operation best suited for that would likely be a full table scan. However, if you specify binds that end up limiting the result set, an index scan might be best. Since you’re using bind variables, each time you execute the query, the input bind values could change. So, the optimizer has to choose a plan that will cover both situations. Most likely, you’ll end up with a full table scan. Listing 5-5 demonstrates each of the scenarios I have covered and shows the execution plan output for each.
上述两个例子中,优化器可能对于决定优化的执行计划有点放难。原因是,如果你所用的用于比较的绑定变量,最终返回的是所有行,最合适的执行计划操作应该是
全表扫描。因为你使用了绑定变量,每次你执行查询,输入的绑定变量可能会改变。这样的话,优化器只能选择一种能照顾两种情况的执行计划。最有可能你最终得
到的是全表扫描。列表5-5演示了我所论及的每种场景且显示了每个的执行计划输出。
Listing 5-5. Different Methods to Express Conditional Logic
SQL> variable empno number
SQL> variable getall number
SQL>
SQL> exec :empno := 7369;
PL/SQL procedure successfully completed.
SQL>
SQL> exec :getall := 1;
PL/SQL procedure successfully completed.
SQL>
SQL> select /* opt1 */ empno, ename from emp
2 where empno = CASE WHEN :GetAll <> 1 THEN :empno ELSE empno END;
EMPNO ENAME
--------------- ----------
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7934 MILLER
14 rows selected.
SQL>
SQL> @pln opt1
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
SQL_ID gwcmrzfqf8cu2, child number 0
-------------------------------------
select /* opt1 */ empno, ename from emp where empno = CASE WHEN :GetAll
<> 1 THEN :empno ELSE empno END
Plan hash value: 3956160932
-----------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | Buffers |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 14 | 8 |
|* 1 | TABLE ACCESS FULL | EMP | 1 | 1 | 14 | 8 |
-----------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("EMPNO"=CASE WHEN (:GETALL<>1) THEN :EMPNO ELSE "EMPNO" END )
19 rows selected.
SQL>
SQL> select /* opt2 */ empno, ename from emp
2 where (:GetAll = 1) OR (empno = :empno);
EMPNO ENAME
--------------- ----------
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7934 MILLER
14 rows selected.
SQL>
SQL> @pln opt2
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
SQL_ID 0yk6utwur2fbc, child number 0
-------------------------------------
select /* opt2 */ empno, ename from emp where (:GetAll = 1) OR (empno =
:empno)
Plan hash value: 3956160932
-----------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | Buffers |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 14 | 8 |
|* 1 | TABLE ACCESS FULL | EMP | 1 | 1 | 14 | 8 |
-----------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(("EMPNO"=:EMPNO OR :GETALL=1))
19 rows selected.
SQL>
SQL> exec :getall := 0;
PL/SQL procedure successfully completed.
SQL>
SQL> select /* opt3 */ empno, ename from emp
2 where empno = CASE WHEN :GetAll <> 1 THEN :empno ELSE empno END;
EMPNO ENAME
--------------- ----------
7369 SMITH
1 row selected.
SQL>
SQL> @pln opt3
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
SQL_ID bfmz26532svu1, child number 0
-------------------------------------
select /* opt3 */ empno, ename from emp where empno = CASE WHEN :GetAll
<> 1 THEN :empno ELSE empno END
Plan hash value: 3956160932
-----------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | Buffers |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 | 8 |
|* 1 | TABLE ACCESS FULL | EMP | 1 | 1 | 1 | 8 |
-----------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("EMPNO"=CASE WHEN (:GETALL<>1) THEN :EMPNO ELSE "EMPNO" END )
19 rows selected.
SQL>
SQL> select /* opt4 */ empno, ename from emp
2 where (:GetAll = 1) OR (empno = :empno);
EMPNO ENAME
--------------- ----------
7369 SMITH
1 row selected.
SQL>
SQL> @pln opt4
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
SQL_ID aqp35x47gpphj, child number 0
-------------------------------------
select /* opt4 */ empno, ename from emp where (:GetAll = 1) OR (empno =
:empno)
Plan hash value: 3956160932
-----------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | Buffers |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 | 8 |
|* 1 | TABLE ACCESS FULL | EMP | 1 | 1 | 1 | 8 |
-----------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(("EMPNO"=:EMPNO OR :GETALL=1))
19 rows selected.
SQL>
SQL> select /* opt5 */ empno, ename from emp
2 where empno = NVL(:empno, empno);
EMPNO ENAME
--------------- ----------
7369 SMITH
1 row selected.
SQL>
SQL> @pln opt5
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
SQL_ID 605p3gyjbw82b, child number 0
-------------------------------------
select /* opt5 */ empno, ename from emp where empno = NVL(:empno, empno)
Plan hash value: 1977813858
-------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | Buffers |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 | 2 |
| 1 | CONCATENATION | | 1 | | 1 | 2 |
|*
2 | FILTER
| | 1 | | 0 | 0 |
| 3 | TABLE ACCESS BY INDEX ROWID | EMP | 0 | 14 | 0 | 0 |
|* 4 | INDEX FULL SCAN | PK_EMP | 0 | 14 | 0 | 0 |
|*
5 | FILTER
| | 1 | | 1 | 2 |
| 6 | TABLE ACCESS BY INDEX ROWID | EMP | 1 | 1 | 1 | 2 |
|* 7 | INDEX UNIQUE SCAN | PK_EMP | 1 | 1 | 1 | 1 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(:EMPNO IS NULL)
4 - filter("EMPNO" IS NOT NULL)
5 - filter(:EMPNO IS NOT NULL)
7 - access("EMPNO"=:EMPNO)
27 rows selected.
SQL>
SQL> select /* opt6 */ empno, ename from emp
2 where (:empno is null) OR (:empno = empno);
EMPNO ENAME
--------------- ----------
7369 SMITH
1 row selected.
SQL>
SQL> @pln opt6
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------
SQL_ID gng6x7nrrrhy9, child number 0
-------------------------------------
select /* opt6 */ empno, ename from emp where (:empno is null) OR
(:empno = empno)
Plan hash value: 3956160932
-----------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | Buffers |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 | 8 |
|* 1 | TABLE ACCESS FULL | EMP | 1 | 2 | 1 | 8 |
-----------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter((:EMPNO IS NULL OR "EMPNO"=:EMPNO))
SQL>
SQL> exec :empno := null;
PL/SQL procedure successfully completed.
SQL>
SQL> select /* opt7 */ empno, ename from emp
2 where empno = NVL(:empno, empno);
EMPNO ENAME
--------------- ----------
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7934 MILLER
14 rows selected.
SQL>
SQL> @pln opt7
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
SQL_ID 83dydzdzbn5zh, child number 0
-------------------------------------
select /* opt7 */ empno, ename from emp where empno = NVL(:empno, empno)
Plan hash value: 1977813858
-------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | Buffers |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 14 | 4 |
|
1 | CONCATENATION |
| 1 | | 14 | 4 |
|* 2 |
FILTER
| | 1 | | 14 | 4 |
| 3 | TABLE ACCESS BY INDEX ROWID | EMP | 1 | 14 | 14 | 4 |
|* 4 | INDEX FULL SCAN | PK_EMP | 1 | 14 | 14 | 2 |
|*
5 | FILTER |
| 1 | | 0 | 0 |
| 6 | TABLE ACCESS BY INDEX ROWID | EMP | 0 | 1 | 0 | 0 |
|* 7 | INDEX UNIQUE SCAN | PK_EMP | 0 | 1 | 0 | 0 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(:EMPNO IS NULL)
4 - filter("EMPNO" IS NOT NULL)
5 - filter(:EMPNO IS NOT NULL)
7 - access("EMPNO"=:EMPNO)
27 rows selected.
SQL>
SQL> select /* opt8 */ empno, ename from emp
2 where (:empno is null) OR (:empno = empno);
EMPNO ENAME
--------------- ----------
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7934 MILLER
14 rows selected.
SQL>
SQL> @pln opt8
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------
SQL_ID 4zvrcjd586tt6, child number 0
-------------------------------------
select /* opt8 */ empno, ename from emp where (:empno is null) OR
(:empno = empno)
Plan hash value: 3956160932
-----------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | Buffers |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 14 | 8 |
|* 1 | TABLE ACCESS FULL | EMP | 1 | 2 | 14 | 8 |
-----------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter((:EMPNO IS NULL OR "EMPNO"=:EMPNO))
For the first two examples where there are two bind variables, you’ll notice that the optimizer
chooses a full table scan operation in both cases. But, notice what happens when you use only a single variable in the second set of examples. In the second case, the optimizer uses a CONCATENATION plan for the NVL predicate and full table scan for the Boolean expression. The CONCATENATION plan is the best in this case as it will work such that when the bind variable is null, the plan will execute the INDEX FULL SCAN operation to get all the rows; when the bind variable is not null, the plan will execute the INDEX UNIQUE SCAN operation to get just the one row that is needed. That way, both options use an optimal execution path.
对于前两个例子,都使用了两个绑定变量。你将注意到优化器对两者都使用的全表扫描。但注意当你只使用单个变量在第二个例子中发生了什么。在第二个例子中,
优化器对NVL谓词使用了连结(CONCATENATION)计划,对布尔表达式使用了全表扫描。连结(CONCATENATION)计划对于绑定变量为
空的情况运行最佳,计划将执行全索引扫描(INDEX FULL SCAN)操作来获取所有的行。当绑定变量不是空,计划将执行唯一索引扫描(INDEX
UNIQUE SCAN)操作取得需要的那一行。这样,两种情况使用了一个优化的执行计划。
In this case, the Boolean logic didn’t give you the best plan so it’s good to know several alternative
ways to formulate the predicate so you can work to achieve the best possible plan. With that in mind,
you could actually have written the query as shown in Listing 5-6.
在这种情况下,布尔逻辑没有给你最佳的执行计划。知道公式化谓词的几种替代方案才好。你就能从中挑选出可能最好的执行计划。本着这种原理,你实际上可以写出List5-6展现的查询。
Listing 5-6. Using a UNION ALL to Handle Conditional Logic 使用UNION ALL处理条件逻辑
SQL> select /* opt9 */ empno, ename from emp
2 where :empno is null
3 union all
4 select empno, ename from emp
5 where :empno = empno;
EMPNO ENAME
--------------- ----------
7369 SMITH
1 row selected.
SQL>
SQL> @pln opt9
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------
SQL_ID ab0juatnpc5ug, child number 0
-------------------------------------
select /* opt9 */ empno, ename from emp where :empno is null union all
select empno, ename from emp where :empno = empno
Plan hash value: 2001993376
------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | Buffers |
------------------------------------------------------------------------------------
|
0 | SELECT STATEMENT | | 1 | | 1 | 2 |
| 1 |
UNION-ALL | | 1 | | 1
| 2 |
|* 2 | FILTER
| | 1 | |
0 | 0 |
| 3 | TABLE ACCESS
FULL | EMP | 0 |
14 | 0 | 0 |
| 4 | TABLE ACCESS BY INDEX ROWID | EMP | 1 | 1 | 1 | 2 |
|* 5 | INDEX UNIQUE SCAN | PK_EMP | 1 | 1 | 1 | 1 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(:EMPNO IS NULL)
5 - access("EMPNO"=:EMPNO)
Similar to the CONCATENATION plan, in this case you get a plan where two separate sub-plans are
unioned together to get the result. If the bind variable is null, you’ll get a full scan operation and will get all rows returned. When the bind variable is not null, you’ll get the unique index scan and return only the one row needed. The FILTER operation acts to determine if the first sub-plan should be executed or not. Notice the predicate information section where step 2 shows filter(:EMPNO IS NULL) indicating that only if the bind is null will the operation actually happen.
类似于连接(CONCATENATION)计划,你将获得一个由两个独立的子计划合并而成的计划返回结果。如果绑定变量是空,你将使用全扫描操作返回所有
的行。当绑定变量不是空,你将使用唯一索引扫描返回唯一需要行。过滤器(FILTER)运算决定第一个子计划是否运行。注意谓词信息段第二部分显示
filter(:EMPNO IS NULL) 指示出仅当绑定变量是空,操作才实际发生。
In general, you’ll find that the optimizer will be able to make better plan operation choices when AND conditions are used. As covered earlier, this is because an OR condition means that there could be two different possible operations that could be used based on how the expression evaluates. With an AND condition, it is more likely that only a single choice, or at least choices that are not opposite in nature, will be considered. So, if you can figure out a way to formulate your predicates to use ANDed conditions solely, you may find that the SQL produces more efficient plans and even is easier to maintain.
一般情况下,你会发现当使用AND条件时,优化器将能做出较好的操作选择计划。如前所述,这是因为:基于表达式被评估的方式,一个OR条件意味着有可能有
两个不同的操作被用到。而用一个AND条件,更有可能只有一种选择,或者至少直觉上不是对立的选择,被考虑。如果你能想出一种只用AND条件的方式公式化
表达你的谓词,你可能发现SQL生成了更有效的执行计划且更容易维护。
Also, if you are writing SQL statements inside a larger code body, like in a PL/SQL procedure, use
conditional constructs in the language and don’t put that logic in the SQL. The simpler you can make
your SQL, and the fewer conditions that have to be handled in the statement directly, the less complexity the optimizer will need to sort through to determine an optimal plan.
还有,如果你在一大段的代码体中写SQL,如在PL/SQL过程中,用到了(PL/SQL)语言中的条件构造,不要将那些逻辑放到SQL中来。尽量让你的SQL简单,在语句中处理的条件越少,优化器需要挑选决定优化计划的复杂度就会越少。
Summary
Questions are an important part of the process of writing good SQL. You begin by understanding the question the SQL needs to answer, then you follow up by asking questions about the data to formulate a SQL statement that is functionally correct as well as optimized for performance. The ability to ask good questions is an intellectual habit that must be developed over time. The more you work to ask questions that clarify and enhance your understanding of what you need to do, the greater your skills as a writer of high-quality, high-performing SQL will become.
总结
(提)问题是写出好SQL过程中的重要部分。开始时,你理解SQL需要回答的问题,然后你问关于数据的问题,用于公式化表达一个功能正确,而且性能优化的
SQL语句。提问题的能力是一种个人习惯需要长时间的培养。澄清和增强理解,你需要做什么的问题,你问的越多,你写出高质量,高性能SQL的技能将变得越
强。
发表评论
-
JavaBean学习三
2012-09-26 22:57 106432.4 Java Event Model Revie ... -
JavaBean 学习二
2012-09-21 00:07 95032.3 Bean Properties ... -
JavaBean 学习一
2012-09-19 00:09 130032.1 Introduction Eve ... -
《Pro Oracle SQL》 读书笔记--Chapter 6--6.2 Execution Plans--之五
2011-11-06 14:11 1149Using Plan Information for Solv ... -
《Pro Oracle SQL》 读书笔记--Chapter 6--6.2 Execution Plans--之四
2011-10-31 23:34 1134Understanding DBMS_XPLAN in Det ... -
《Pro Oracle SQL》--Chapter 6--6.2 Execute Plans--之三
2011-10-26 22:42 889Identifying SQL Statements for ... -
《Pro Oracle SQL》--Chapter 6--6.2 Execution Plans--之二
2011-10-25 07:11 1009Collecting the Plan Statistics ... -
《Pro Oracle SQL》--Chapter 6 SQL Execution Plans --6.2 Execution Plans--之一
2011-10-22 10:17 1024Execution Plans 执行计划 (page 1 ... -
《Pro Oracle SQL》--Chapter 6--6.1 Explain Plans--之三
2011-10-21 06:35 1256Reading the Plan 解读计划 (page1 ... -
《Pro Oracle SQL》--Chapter 6--6.1 Explain Plans--之二
2011-10-17 23:06 1102Understanding How EXPLAIN PLAN ... -
《Pro Oracle SQL》--Chapter 6--6.1 Explain Plans--之一
2011-10-17 15:14 1087Chapter 6--SQL Execution Plans ... -
《Pro Oracle SQL》--Chapter 5--5.5 Questions about Data
2011-10-15 00:42 763Questions about Data 关于数据的问题 ... -
《Pro Oracle SQL》--Chapter 5--5.4 Questions about the Question
2011-10-12 00:36 12465.4 Questions about the Questio ...
相关推荐
标题 "kmod-oracleasm-2.0.6.rh1-3.el6.x86_64" 提供的信息表明这是一个与Oracle相关的模块,具体是Oracle ASM (Automatic Storage Management) 的驱动模块,版本为2.0.6,适配Red Hat Enterprise Linux 6.5的64位...
Oracle Support for Oracle ASM (Automatic Storage Management) 和 Kmod-OracleASM 包是Oracle数据库系统在Linux环境下进行存储管理的关键组件。这些包确保了在Red Hat Enterprise Linux (RHEL)、CentOS以及Oracle ...
《涂抹Oracle-三思笔记之一步步学Oracle》-李丙洋-源代码-6961.rar 目录5内文件与书中第5章代码段落一一对应; 目录8内文件为书中第8章备份脚本; 目录10内文件为书中第10章出现的部分脚本,分为两部分:physical...
对于Oracle,它通常依赖于Oracle的逻辑日志读取技术,如Logical Standby或GoldenGate,来跟踪并捕获DML(INSERT, UPDATE, DELETE)操作。 接下来,我们将讨论实现这个“fink cdc datastream 捕获Oracle19c日志demo...
Oracle Data Guard是Oracle数据库系统提供的一种高可用性和灾难恢复解决方案,它通过创建并维护一个或多个备用数据库,来保护关键业务数据免受意外损失或系统故障的影响。在本压缩包中,"dataguard教材"包含了对Data...
在本教程中,我们将详细介绍如何在VMware WorkStation环境下搭建Oracle 12c RAC (Real Application Clusters)集群,该集群将基于Redhat系统并使用iscsi实现共享存储挂载。以下是整个过程的详细步骤: 一、IP地址...
Chapter 5 - Page Setup and Printing Chapter 6 - Formulas and Functions Chapter 7 - Using a Formula to Join the Contents of Multiple Cells Chapter 8 - Modifying Workbooks Chapter 9 - Working with ...
- **JDeveloper**: An integrated development environment (IDE) provided by Oracle for building applications using Java and PL/SQL. This includes creating, editing, testing, and debugging PL/SQL code. ...
LogicalDOC是文档管理和协作系统。该软件具有许多功能,可以为任何组织和个人安全,安全地组织,索引,检索,控制和分发重要的业务文档。 公司使用纸质流程(例如打印,邮寄和手动归档纸质文档)的日子已经一去不...
ERWin是一款功能强大的数据建模工具,可以连接多种类型的数据库,包括SQL Server 2000和Oracle 10g。然而,在连接数据库时,用户可能会遇到各种错误,例如数据库不存在、表不存在等错误。下面我们将详细介绍ERWin...
### CDC操作Sqlserver2008 #### 概述 变更数据捕获(Change Data Capture,简称CDC)是SQL Server的一项重要功能,主要用于记录数据库表中的数据更改历史。这一功能在进行数据分析、日志记录、数据复制等场景下...
Chapter 5 - RAID Levels and Logical Volumes Chapter 6 - File Systems and Network Protocols Chapter 7 - SAN Backup and Recovery Chapter 8 - Storage Security Chapter 9 - Storage Networks ...
formatted-task021-mctaco-grammatical-logical.json
SQL fundamentals, create tables, and define data integrity Understand logical query processing Query multiple tables using joins and subqueries Simplify code and improve maintainability with table ...
根据提供的文档信息,我们可以深入探讨其中涉及的数据库原理及应用SQL相关的知识点。下面将逐一解析题目中的关键概念和原理。 ### 数据库原理及应用SQL-习题集知识点解析 #### 1. ER模型(实体关系模型) - **知识...
属性使用逻辑 是规则,用于强制使用CSS中的 。 物理尺寸和方向被描述左到右,从上到下,而它们的逻辑对应描述开始到另一端,内联或块。 例如,要在段落开头之前添加间距,我们可以使用physical padding-left属性。...
离线安装包,亲测可用
2. **设置Oracle数据库**:在Oracle 11G中启用CDC,需要创建逻辑复制表(Logical replication tables)并启动相关的数据库监听服务。这通常涉及到创建变更表空间、开启数据库归档日志模式、创建和配置捕获进程以及...