在Oracle中使用CASE的哪种方法更好?

时间:2012-11-22 03:45:07

标签: database oracle case

我很好奇这些查询(性能或其他)更好。

    SELECT some_column,
    CASE case_column
         WHEN 1 THEN 'a'
         WHEN 2 THEN 'a'
         WHEN 3 THEN 'a'
         WHEN 5 THEN 'b'
         WHEN 6 THEN 'b'
         ...
    END AS case_column_str
    FROM some_table ORDER BY case_column_str

    SELECT some_column,
    CASE 
         WHEN case_column=1 OR case_column=2 OR case_column=3 THEN 'a'
         WHEN case_column=5 OR case_column=6 THEN 'b'
         ...
    END AS case_column_str
    FROM some_table ORDER BY case_column_str

这些查询中的任何一个都有优势吗?除了第二个能够使用其他字段进行更多过滤之外,两者之间是否存在显着差异?如果我要过滤一个列怎么办?

5 个答案:

答案 0 :(得分:3)

任何体面的优化器都会将两者视为基本相同;你不太可能衡量绩效差异。 Oracle有一个足够好的优化器,你很难衡量差异。您可以查看查询计划,但如果它们完全相同,请不要感到惊讶。

答案 1 :(得分:3)

它们被解析相同。

13:41:48 SYSTEM@oars_sandbox> create table t as select mod(rownum,5) val from dual connect by rownum <= 1e5;

Table created.                                                                                              

Elapsed: 00:00:00.21                                                                                        

注意“列投影信息”。第一种情况:

13:43:51 SYSTEM@oars_sandbox> ed                                                    
Wrote file S:\\tools\buffer.sql                                                     

  1  SELECT CASE val                                                                
  2           WHEN 1 THEN 'a'                                                       
  3           WHEN 2 THEN 'a'                                                       
  4           WHEN 3 THEN 'a'                                                       
  5           WHEN 5 THEN 'b'                                                       
  6         END AS case_column_str                                                  
  7    FROM t                                                                       
  8*  ORDER BY case_column_str                                                      
13:44:32 SYSTEM@oars_sandbox> @xplan                                                

PLAN_TABLE_OUTPUT                                                                   
------------------------------------------------------------------------------------
Plan hash value: 961378228                                                          

----------------------------------------------------------------------------------- 
| Id  | Operation          | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | 
----------------------------------------------------------------------------------- 
|   0 | SELECT STATEMENT   |      |   114K|  1450K|       |   591   (2)| 00:00:08 | 
|   1 |  SORT ORDER BY     |      |   114K|  1450K|  2256K|   591   (2)| 00:00:08 | 
|   2 |   TABLE ACCESS FULL| T    |   114K|  1450K|       |    44   (3)| 00:00:01 | 
----------------------------------------------------------------------------------- 

Query Block Name / Object Alias (identified by operation id):                       
-------------------------------------------------------------                       

   1 - SEL$1                                                                        
   2 - SEL$1 / T@SEL$1                                                              

Column Projection Information (identified by operation id):                         
-----------------------------------------------------------                         

   1 - (#keys=1) CASE "VAL" WHEN 1 THEN 'a' WHEN 2 THEN 'a' WHEN 3 THEN             
       'a' WHEN 5 THEN 'b' END [1]                                                  
   2 - "VAL"[NUMBER,22]                                                             

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

第二种情况:

13:44:36 SYSTEM@oars_sandbox> ed                                                    
Wrote file S:\\tools\buffer.sql                                                     

  1  SELECT CASE WHEN val=1 OR val=2 OR val=3 THEN 'a'                              
  2           WHEN val=5 OR val=6 THEN 'b'                                          
  3    END AS case_column_str                                                       
  4    FROM t                                                              
  5*  ORDER BY case_column_str                                                      
13:45:53   6                                                                        
13:45:55 SYSTEM@oars_sandbox> @xplan                                                

PLAN_TABLE_OUTPUT                                                                   
------------------------------------------------------------------------------------
Plan hash value: 961378228                                                          

----------------------------------------------------------------------------------- 
| Id  | Operation          | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | 
----------------------------------------------------------------------------------- 
|   0 | SELECT STATEMENT   |      |   114K|  1450K|       |   591   (2)| 00:00:08 | 
|   1 |  SORT ORDER BY     |      |   114K|  1450K|  2256K|   591   (2)| 00:00:08 | 
|   2 |   TABLE ACCESS FULL| T    |   114K|  1450K|       |    44   (3)| 00:00:01 | 
----------------------------------------------------------------------------------- 

Query Block Name / Object Alias (identified by operation id):                       
-------------------------------------------------------------                       

   1 - SEL$1                                                                        
   2 - SEL$1 / T@SEL$1                                                              

Column Projection Information (identified by operation id):                         
-----------------------------------------------------------                         

   1 - (#keys=1) CASE "VAL" WHEN 1 THEN 'a' WHEN 2 THEN 'a' WHEN 3 THEN             
       'a' WHEN 5 THEN 'b' END [1]                                                  
   2 - "VAL"[NUMBER,22]                                                             

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

解释计划查询:

  select * from table(dbms_xplan.display(null, null, 'all'));  

答案 2 :(得分:1)

两种形式的CASE语法允许我们使用不同的条件。

第一种形式仅适用于对单个列进行过滤,但即便如此,它也非常严格。根据你的示例规则,我仍然会选择使用第二个变体,但是使用较简洁的公式......

CASE
    WHEN case_column in (1,2,3) THEN 'a'
    WHEN case_column in (5,6) THEN 'b'
    ELSE 'c'
END CASE

...或者......或者......

CASE
    WHEN case_column <= 3 THEN 'a'
    WHEN case_column between 5 and 6 THEN 'b'
    ELSE 'c'
END CASE

答案 3 :(得分:0)

这里你提到了两种案例陈述。 第一个例子是正常案例陈述。 第二个例子是搜索的案例陈述。

第一种形式几乎相当于oracle的解码功能。所以我没有看到任何特殊用途的这种情况。

而第二种形式就像if else编码范式。通过这个可以检查多个条件,否则无法以第一种形式检查。

从性能角度来看,两种方式之间没有区别。当两个查询在SQL DEVELOPER中执行时,两个查询都给出相同的成本值。

希望这会有所帮助。!!

答案 4 :(得分:-1)

SELECT some_column,
CASE 
     WHEN case_column=1 or case_column=2 or case_column=3 THEN 'a'
     WHEN case_column=5 or case_column=6 THEN 'b'
     ...
END as case_column_str
FROM some_table order by case_column_str

这好得好,好像其中任何一个都是真的,我们不必检查其余的条件

第一种选择不是这种情况,在那里我们必须逐一传递每个条件。