我很好奇这些查询(性能或其他)更好。
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
这些查询中的任何一个都有优势吗?除了第二个能够使用其他字段进行更多过滤之外,两者之间是否存在显着差异?如果我要过滤一个列怎么办?
答案 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
这好得好,好像其中任何一个都是真的,我们不必检查其余的条件
第一种选择不是这种情况,在那里我们必须逐一传递每个条件。