0

我很好奇在这些查询中哪个更好(性能或任何东西)。

    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

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

4

5 回答 5

3

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

于 2012-11-22T04:25:14.070 回答
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'));  
于 2012-11-22T05:49:03.997 回答
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
于 2012-11-23T06:01:37.077 回答
0

在这里,您提到了两种案例陈述。第一个例子是正常的案例陈述。 第二个示例是搜索的案例语句。

第一种形式几乎等同于oracle 的解码功能。所以我看不出这种情况有什么特别的用途。

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

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

希望这可以帮助。!!

于 2015-03-25T04:15:40.457 回答
-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

这要好得多,就好像其中任何一个在这种情况下为真一样,我们不必检查其余条件

第一个选项不是这种情况,在那里我们必须一个一个地通过每个单独的条件。

于 2012-11-22T03:53:28.127 回答