Decode Vs Case: context switching?
So I was told recently that among other reasons, CASE is "better" than Decode in SQL statements because Decode context switches to PL/SQL to perform the checks.
I can't find anything in the documentation to support this.
this site here:
http://www.dba-oracle.com/oracle_news/2005_11_23_case_decode_machinations.htm
mentions that one of the disadvantages of decode is that it's post-retrieval, but it also seems to mention that so is CASE.
anyone have any idea where someone may have got the "context switching" idea from?
have often wondered why you would use CASE in PL/SQL when it has IF THEN control structures. Yes, you could, however readability would suffer. But what is more important CASE has a form where expression is evaluated only once:
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
2 X NUMBER;
3 BEGIN
4 PKG1.CNT := 2;
5 X := CASE PKG1.F1
6 WHEN 1 THEN 1
7 WHEN 2 THEN 2
8 WHEN 3 THEN 3
9 END;
10 DBMS_OUTPUT.PUT_LINE('X = ' || X);
11 DBMS_OUTPUT.PUT_LINE('PKG1.CNT = ' || PKG1.CNT);
12 END;
13 /
Call to PKG1.F1
X = 3
PKG1.CNT = 3
PL/SQL procedure successfully completed.
SQL> DECLARE
2 X NUMBER;
3 BEGIN
4 PKG1.CNT := 2;
5 IF PKG1.F1 = 1
6 THEN X := 1;
7 ELSIF PKG1.F1 = 2
8 THEN X := 2;
9 ELSIF PKG1.F1 = 3
10 THEN X := 3;
11 END IF;
12 DBMS_OUTPUT.PUT_LINE('X = ' || X);
13 DBMS_OUTPUT.PUT_LINE('PKG1.CNT = ' || PKG1.CNT);
14 END;
15 /
Call to PKG1.F1
Call to PKG1.F1
Call to PKG1.F1
X =
PKG1.CNT = 5
PL/SQL procedure successfully completed.
SQL> In such case you would have to introduce a temp variable:
SQL> CREATE OR REPLACE
2 PACKAGE PKG1
3 IS
4 CNT NUMBER;
5 FUNCTION F1 RETURN NUMBER;
6 END;
7 /
Package created.
SQL> CREATE OR REPLACE
2 PACKAGE BODY PKG1
3 IS
4 FUNCTION F1 RETURN NUMBER
5 IS
6 BEGIN
7 DBMS_OUTPUT.PUT_LINE('Call to PKG1.F1');
8 CNT := CNT + 1;
9 RETURN CNT;
10 END;
11 END;
12 /
Package body created.
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
2 X NUMBER;
3 BEGIN
4 PKG1.CNT := 2;
5 X := CASE PKG1.F1
6 WHEN 1 THEN 1
7 WHEN 2 THEN 2
8 WHEN 3 THEN 3
9 END;
10 DBMS_OUTPUT.PUT_LINE('X = ' || X);
11 DBMS_OUTPUT.PUT_LINE('PKG1.CNT = ' || PKG1.CNT);
12 END;
13 /
Call to PKG1.F1
X = 3
PKG1.CNT = 3
PL/SQL procedure successfully completed.
SQL> DECLARE
2 X NUMBER;
3 TMP NUMBER;
4 BEGIN
5 PKG1.CNT := 2;
6 TMP := PKG1.F1;
7 IF TMP = 1
8 THEN X := 1;
9 ELSIF TMP = 2
10 THEN X := 2;
11 ELSIF TMP = 3
12 THEN X := 3;
13 END IF;
14 DBMS_OUTPUT.PUT_LINE('X = ' || X);
15 DBMS_OUTPUT.PUT_LINE('PKG1.CNT = ' || PKG1.CNT);
16 END;
17 /
Call to PKG1.F1
X = 3
PKG1.CNT = 3
PL/SQL procedure successfully completed.
SQL> SY.
Similar Messages
-
Reg : Context-switching for built-in functions -
Hi Experts,
Asking this question just out of curiosity to know the internal concepts.
In a SQL query often we use the in-built Oracle functions like LOWER, UPPER, etc.
In this case, does context-switch happen?
Will I be able to look into the code of these functions after logging into SYS schema as SYSDBA?
FYI - I've Oracle XE 11.2 installed in my home pc (currently in office, so don't have access to it).
Help much appreciated!
Thanks,
Ranitranit B wrote:
Hi Experts,
Asking this question just out of curiosity to know the internal concepts.
In a SQL query often we use the in-built Oracle functions like LOWER, UPPER, etc.
In this case, does context-switch happen?No, because many of these functions are compiled at low level (C language) into the SQL and the PL/SQL engines, so each has their own 'copy' (in theory) to execute without having to context switch to the other engine.
Will I be able to look into the code of these functions after logging into SYS schema as SYSDBA?No, they are written in C and compiled into the engines.
In terms of the supplied packages (rather than built in functions), many of those are wrapped by oracle so you can only see the public interface, not the actual body code. -
Theory: Firewalls essentially partition the Java Card platform’s object system into separate
protected object spaces called contexts. The
firewall is the boundary between one context and another. The Java Card RE shall
allocate and manage a context for each Java API package containing applets1. All
applet instances within a single Java API package share the same context. There is
no firewall between individual applet instances within the same package. That is, an
applet instance can freely access objects belonging to another applet instance that
resides in the same package.
That is the theory. What happens in my case. My Java Card project contains three packages and in one there is one Java Card applet. Splitting to three package was necessary because the application is large. What about the object instances from other packages. Are they assigned to other context and what happens when java card applet instance access these objects? Is context switching is happening?Patrick,
Don't worry about context switching. Build a good load test. Run it against
a "best guess" number of exec threads. Increase the number of threads and
run again. If overall throughput drops, then decrease the number of threads
and run again. Start with coarse increments (5 threads?) and work from there
until you get the best setting.
Peace,
Cameron Purdy
Tangosol, Inc.
http://www.tangosol.com/coherence.jsp
Tangosol Coherence: Clustered Replicated Cache for Weblogic
"Patrick Acheson" <[email protected]> wrote in message
news:3d5aae20$[email protected]..
>
In setting the executeThreadCount variable for Weblogic 5.10, if thevariable is
too high there will be a lot of context switching going on. What wouldconstitute
a lot of context switching as opposed to what would be a normal orexpected amount?
Our executeThreadCount is set at 100 and we have 4 CPUs. In Perfmon,about 10%
of the threads show 1 to 2 context switches per second. -
Context switching / Threads
Hello !
The following program is for 3 Threads which do context switching.
Often we get '0' zero for the low priority thread when we run this program.
MY QUESTION IS WHY DO WE GET ZERO ?
As far as my understanding is concerned; even if preemptive multitasking is done by the threads,
the low priority thread should have run through few iterations and thus giving some value other
than zero '0'.
Secondly most of the time we get negative values for the high priority thread. Why is that ?
Is it because of the fact that volatile sets the variable 'running' to some different value ?
The speed of my processor is 1.5GHz.
GOD BLESS YOU.
NADEEM.
// Demonstrates threads priorities.
class Clicker implements Runnable {
int click = 0;
String name ;
Thread t ;
private boolean running = true ;
public Clicker(String tname, int p) {
name = tname ;
t = new Thread(this, name);
t.setPriority(p);
System.out.println("Current Thread is " + t + " " + t.getPriority());
public void start() {
t.start();
public void run() {
while (running) {
click++;
public void stop() {
running = false ;
class HLPriority {
public static void main(String args[]) {
System.out.println("Active Count : " + Thread.activeCount());
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
Clicker hi = new Clicker("Hi", Thread.NORM_PRIORITY + 2);
Clicker lo = new Clicker("Lo", Thread.NORM_PRIORITY - 2);
System.out.println("Active Count : " + Thread.activeCount());
lo.start();
hi.start();
try {
System.out.println("Sleeping Thread : " + Thread.currentThread());
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Main Thread interrupted : " + e);
hi.stop();
lo.stop();
try {
hi.t.join();
lo.t.join();
} catch (InterruptedException e) {
System.out.println("Interrupted Exception caught : " + e);
System.out.println("Low priority thread : " + lo.click);
System.out.println("Hi priority thread : " + hi.click);
}Hello !
The following program is for 3 Threads which do
context switching.
Often we get '0' zero for the low priority thread when
we run this program.
MY QUESTION IS WHY DO WE GET ZERO ?Presumably because the low priority thread gets no CPU time.
>
As far as my understanding is concerned; even if
preemptive multitasking is done by the threads,
the low priority thread should have run through few
iterations and thus giving some value other
than zero '0'.You can't make ANY assumptions about when or how much CPU time a given thread will get. Why don't you let your main thread sleep longer--a minute or 5 or ten--and see if LO gets some cycles then.
Secondly most of the time we get negative values for
the high priority thread. Why is that ?count = Integer.MAX_VALUE;
count++; // --> Integer.MIN_VALUE (-2^31)
I guess 10 seconds is enough time for a thread in a tight loop to count to 2 billion.
Is it because of the fact that volatile sets the
variable 'running' to some different value ?Volatile does nothing of the sort, and, in any case, isn't even in your code.
GOD BLESS YOU.I didn't sneeze. -
About case and switch in multiple condition step in workflow.
i ve some information about case and switch in multiple condition in workflow.
case - static determination
switch - runtime determination.
but i want brief explanation about case and switch and difference please help me.....hi velmurugan............
in case,
we can have only one value for comparison and can have any number of branches for it.
in switch,
we can compare any number of values and have any number of branches.
eg:
consider i am triggering a workflow for purchase order change and i am having a multiple condition step.
if i am going for a case:
i can have only on value (ie po number/vendor number.....) as a parameter and can check different values with it. ( eg vendor number < 1000
vendor number > 1000.... so on)
a branch will be created for each condition.
if i am going for a switch:
i can take any parameter needed. (eg: vendor number > 1000
order type = 'NB' .... so on)
so a single branch can have any number of comparisons with the help of 'and' and 'or' operators and i can have any parameter for my condition.
---regards,
alex b justin -
Hi
I need small clarification about difference between decode and case
Thanks who visit my threadAnd for those people who can't be ar$ed to follow links...
Decode allows for conditional output where the conditions are straightforward matches between values.
Case allows for regular conditions to be used such as greater than, less than etc.
Some of the things done by case can be achieved through decode as well but in a more convoluted manner than simply using case.
;) -
What will be good for proformance wise:
Decode or Case in a sql statement.?????See the following link for Tom Kyte's opinion (point #4 in his first answer):
http://asktom.oracle.com/pls/ask/f?p=4950:8:16717708356827415201::NO::F4950_P8_DISPLAYID,F4950_P8_CRITERIA:1243867216406 -
Which is the best decode or case
Hi,
When you check performance wise which is the best one decode or case?
Thanks,> You mean CPU processor speed or oracle buffer(SGA).
Neither. CPU architecture. RISC vs CISC vs ..
On a PA-RISC1 CPU a DECODE is just a tad faster than a CASE. On an AMD64 CPU, the reverse is true.
> When I increase memory, The case and decode performance will increase?
No. A CASE and a DECODE does not need memory to work faster. It is a set of machine code instructions that needs to compare values to determine a result. It depends on just how fast the CPU can execute this set of machine code instructions.
A faster CPU will make a very significant difference. An AMD64 Opteron CPU is a couple of times faster than a PA-RISC1 CPU.
I had this exact same conversation back in 2006 on this forum - and posted [url
http://forums.oracle.com/forums/thread.jspa?messageID=1346165�]this benchmark to show that the decision of using CASE or DECODE is not a decision that should be based on raw performance. -
I have emp_allocation table. It has data as below
EMPID YEAR MONTH
X 2006 JAN
X 2006 MAR
Y 2006 JAN
Y 2006 FEB
Y 2006 MAR
I want SQL Query(Without Decode or Case) which will give output as below
EMPID YEAR JAN FEB MAR APR JUN JUL
X 2006 Y N Y
Y 2006 Y Y YWhy you'd want to do it this way I do not know, but if you insist...
SQL> ed
Wrote file afiedt.buf
1 WITH t AS (select 'X' AS EMPID, 2006 AS YEAR, 'JAN' AS MONTH FROM DUAL UNION ALL
2 select 'X', 2006, 'MAR' FROM DUAL UNION ALL
3 select 'Y', 2006, 'JAN' FROM DUAL UNION ALL
4 select 'Y', 2006, 'FEB' FROM DUAL UNION ALL
5 select 'Y', 2006, 'MAR' FROM DUAL)
6 -- END OF TEST DATA
7 SELECT EMPID, YEAR, NVL(MAX(JAN),'N') AS JAN, NVL(MAX(FEB),'N') AS FEB, NVL(MAX(MAR),'N') AS MAR, NVL(MAX(APR),'N') AS APR
8 FROM
9 (
10 SELECT EMPID, YEAR, 'Y' AS JAN, NULL AS FEB, NULL AS MAR, NULL AS APR FROM t WHERE MONTH = 'JAN' UNION ALL
11 SELECT EMPID, YEAR, NULL AS JAN, 'Y' AS FEB, NULL AS MAR, NULL AS APR FROM t WHERE MONTH = 'FEB' UNION ALL
12 SELECT EMPID, YEAR, NULL AS JAN, NULL AS FEB, 'Y' AS MAR, NULL AS APR FROM t WHERE MONTH = 'MAR' UNION ALL
13 SELECT EMPID, YEAR, NULL AS JAN, NULL AS FEB, NULL AS MAR, 'Y' AS APR FROM t WHERE MONTH = 'APR'
14 )
15 GROUP BY EMPID, YEAR
16* ORDER BY 1,2
SQL> /
E YEAR J F M A
X 2006 Y N Y N
Y 2006 Y Y Y N
SQL> -
Hi,
What is the difference between decode and case?
What are the cases in which we can use Decode and case
Thanxyou can not put Search CASE statements by using DECODE
Eg:
SELECT AVG(CASE WHEN e.salary > 2000 THEN e.salary ELSE 2000 END) "Average Salary" FROM employees e;Can't we?
select avg(decode(sign(e.salary - 2000), 1, e.salary, 2000)) "Average Salary" from employees e; -
Overhead of SQL to PL/SQL context switch using an inline function
Hi,
We have a bit of sql in a third party application that uses an inline pl/sql function to do some security checks.
These security checks are redundant in our system - we don't use the functionality so the result is always true, but the function is always called for each line of output, which is over a thousand for a lot of records.
The function itself is fairly lightweight in our environment - the tables it uses are empty so each iteration of the function is quite quick (about .1 of a second per query in total, vs 12-15 seconds for the 'main' query). What I was wondering if there is any way of measuring the overhead of just doing the function calls.
If I do a trace of the session I see the timings and cost of the 'main' sql query, and the breakdown of the 2 sql statements that have been called in the function (with over 1000 executions each) but is there any way to measure how much of the time to execute the main query is spent doing the context switch?
Regards,
CarlYou could knock up some example to show the timings and measure it...
The following shows an example using context switching from PL/SQL to SQL and back in a loop, which gives an idea of the performance difference...
SQL> ed
Wrote file afiedt.buf
1 declare
2 v_sysdate DATE;
3 begin
4 v_sysdate := SYSDATE;
5 INSERT INTO mytable SELECT rownum FROM DUAL CONNECT BY ROWNUM <= 1000000;
6 DBMS_OUTPUT.PUT_LINE('Single Transaction: Time Taken: '||ROUND(((SYSDATE-v_sysdate)*(24*60*60)),0));
7 EXECUTE IMMEDIATE 'TRUNCATE TABLE mytable';
8 v_sysdate := SYSDATE;
9 FOR i IN 1..1000000
10 LOOP
11 INSERT INTO mytable (x) VALUES (i);
12 END LOOP;
13 DBMS_OUTPUT.PUT_LINE('Multi Transaction: Time Taken: '||ROUND(((SYSDATE-v_sysdate)*(24*60*60)),0));
14 EXECUTE IMMEDIATE 'TRUNCATE TABLE mytable';
15* end;
SQL> /
Single Transaction: Time Taken: 1
Multi Transaction: Time Taken: 37
PL/SQL procedure successfully completed.
SQL>Likewise you could time a query with X number of rows calling a PL/SQL function and not calling a PL/SQL function to see the difference. The more rows you do, the better idea you'll get of the difference.
;) -
Hi all,
select
id
,one
,two
From
(select id
, one
, two
, Max(decode(TYPE, "ER", 3*4, 4*7)
from
(select id
, sum(one) as one
, sum(two) as two
from t1
group by id)
group by id, one, two
) temp inner join t2....
The above query is just a sample structure to tell the problem that i am facing. It works fine, but i need to convert it to ANSI Standard.
Hence I need to convert the DECODE to CASE statement. but if i convert to CASE, i need to use any of the GROUP BY FUNCTIONS, but if i use the MAX of any group by functions, the result would be wrong...how to overcome it
ThanksHi,
Yes I did a silly mistake, the code I gave was for only the decode but when I converted it to case statement, there was a silly mistake, which i corrected.
Now i corrected it to
Select
COL1
, Col2
, MAX(CASE WHEN Upper(TYPE) = 'YR' THEN Round(3.43*3, 2) END) AS CALC1
, Max(CASE WHEN Upper(TYPE) = 'ZP' THEN Round(3.12*12, 2) END) AS CALC2
From
Group by....
but now when i add a sum of the calc1 & calc2, I am not getting any results the column is blank. Is there anything that i missed
Select
COL1
, Col2
, MAX(CASE WHEN Upper(TYPE) = 'YR' THEN Round(3.43*3, 2) END) AS CALC1
, Max(CASE WHEN Upper(TYPE) = 'ZP' THEN Round(3.12*12, 2) END) AS CALC2
, (MAX(CASE WHEN Upper(TYPE) = 'YR' THEN Round(3.43*3, 2) END
+ Max(CASE WHEN Upper(TYPE) = 'ZP' THEN Round(3.12*12, 2) END)) as SUM3
From
Group by....
Thanks -
I'm a beginner with Oracle SQL and I have a select statement with the following code:
max(decode(EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_CD, '1000', EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_RESULT_TEST_SCORE, '2000', EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_RESULT_TEST_SCORE, '4000', EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_RESULT_TEST_SCORE))
I've been asked to create several more columns in a similar manner. My concern is that since this relies on 'decode' which is less efficient than 'case', that adding more columns using this approach will bog down an already not efficient query. Bottom line my problem is that I don't really understand this 'decode' since all the explanations of 'decode' I've found stop at four parameters.
Could someone please show me how the expression above looks in If-then-else terms as well as comment on how to convert this 'decode' to 'case'? Thanks in advance!1) The if-then-else stmt
-- Longest way
if EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_CD = '1000' then
return value of EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_RESULT_TEST_SCORE;
elsif EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_CD = '2000' then
return value of EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_RESULT_TEST_SCORE;
elsif EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_CD = '4000' then
return value of EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_RESULT_TEST_SCORE;
else return null;
end if;
-- shorter way
if EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_CD = '1000' or
EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_CD = '2000' or
EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_CD = '4000' then
return value of EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_RESULT_TEST_SCORE;
else return null;
end if;
-- shortest if-then-else code
if EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_CD in ('1000', '2000', '4000') then
return value of EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_RESULT_TEST_SCORE;
else return null;
end if;
2) The MAX() function
The MAX function will return the greatest value of EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_RESULT_TEST_SCORE in step 1 above.
2) Using CASE
select
max(case when (EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_CD in('1000','2000','4000'))
then EDW.V_RECRUIT_TEST_RESULT_HIST.TEST_RESULT_TEST_SCORE end)
into ...your_item_or_local_variable
from EDW.V_RECRUIT_TEST_RESULT_HIST;
Try the code above, good luck
v/r
Vien Tran -
What is better and fast to use between decode and case
Hi friends,
i wanted to know what is better to use decode or case in sql,which gives faster result.
thks
sonal....Here's a very simple timing comparison. This table (actually it's a partition) has a little over 1 million rows.
As you can see, the timing difference is trivial. (I ran an earlier query to fetch the blocks from disk).
SQL> select sum(decode(balloon_flag
2 ,'Y',1
3 ,0
4 )
5 ) bal_count
6 from prod.loan_master
7 where report_date = to_date('31-DEC-2005');
BAL_COUNT
9036
Elapsed: 00:00:07.65
SQL> select sum(case balloon_flag
2 when 'Y' then 1
3 else 0
4 end
5 ) bal_count
6 from prod.loan_master
7 where report_date = to_date('31-DEC-2005');
BAL_COUNT
9036
Elapsed: 00:00:07.68
SQL> select sum(case
2 when balloon_flag = 'Y' then 1
3 else 0
4 end
5 ) bal_count
6 from prod.loan_master
7 where report_date = to_date('31-DEC-2005');
BAL_COUNT
9036
Elapsed: 00:00:07.46 -
How does decode and case works?
Hi,
I want to know how decode and case works? How they process the arguements. Please explain me with some examples.
Thanks,
Sarav
Edited by: 943941 on Jul 3, 2012 1:42 AMwelcome
check this link
https://forums.oracle.com/forums/ann.jspa?annID=1535
you will find everything you need
DECODE compares expr to each search value one by one. If expr is equal to a search, then Oracle Database returns the corresponding result. If no match is found, then Oracle returns default. If default is omitted, then Oracle returns null.
This example decodes the value warehouse_id. If warehouse_id is 1, then the function returns 'Southlake'; if warehouse_id is 2, then it returns 'San Francisco'; and so forth. If warehouse_id is not 1, 2, 3, or 4, then the function returns 'Non domestic'.
SELECT product_id,
DECODE (warehouse_id, 1, 'Southlake',
2, 'San Francisco',
3, 'New Jersey',
4, 'Seattle',
'Non domestic')
"Location of inventory" FROM inventories
WHERE product_id < 1775;Edited by: user 007 on Jul 3, 2012 2:40 PM
Maybe you are looking for
-
Hi, i'm trying to use JMF with eclipse. I have downloaded the software from: [JMF 2.1.1e Software|http://java.sun.com/products/java-media/jmf/2.1.1/download.html] I have added the all the jars in the lib folder to the eclipse class path by going to:
-
How to return to my movie's timeline
I created a movie called "ElverPark" about my nephews at the park. Later I created a movie called "Drone" about a drone test flight. I just re-opened iMovie and have: 1. Drone assets on top left 2. Drone preview on top right 3. Drone timeline (vid
-
Naming Standards: What are you using?
I'd like to hear what different organizations are using for naming standards to manage their XI environment. When you have a new interface or need to call up an existing interface, how do you know where to find them? Do you break out your interface
-
Hi All, I would like to use my company´s logo in my signature. But I don´t want to send it as attachment every time I send an e-mail. In thunderbird I could select an html file as signature which just links to an image on our server. Is there any sim
-
I am using AE CS4 on a PC. I want to export my project to a PAL Widescreen size QT MOV file (1024x576px). The project is 25 minutes long. When I do this using the default settings in Add to Render Queue, the MOV file it creates is approx 1.5 Gb in si