缺少GROUP BY表示式可以順利執行的問題
Oracle9204上執行一個明顯語法錯誤的SQL,卻可以得到查詢結果。
首先重現一下問題:
SQL> CREATE TABLE T1 AS SELECT * FROM DBA_OBJECTS;
表已建立。
SQL> CREATE TABLE T2 AS SELECT * FROM DBA_USERS;
表已建立。
SQL> SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE;
SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE
*
第 1 行出現錯誤:
ORA-00979: 不是 GROUP BY 表示式
這個SQL由於GROUP BY語句中確少OWNER欄位,因此執行報錯。
但是把這個SQL內嵌到子查詢中,居然可以得到結果:
SQL> SELECT USERNAME, OBJECT_TYPE, CN
2 FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE), T2
3 WHERE USERNAME = OWNER
4 AND USERNAME LIKE 'SYS%';
USERNAME OBJECT_TYPE CN
------------------------------ ------------------ ----------
SYS LOB 28
SYS TYPE 478
SYS VIEW 2112
.
.
.
SYSTEM INDEX PARTITION 48
SYSTEM TABLE PARTITION 53
已選擇42行。
檢查SQL的執行計劃,發現是MERGE JOIN:
SQL> SELECT USERNAME, OBJECT_TYPE, CN
2 FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE), T2
3 WHERE USERNAME = OWNER
4 AND USERNAME LIKE 'SYS%';
執行計劃
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE
1 0 SORT (GROUP BY)
2 1 MERGE JOIN
3 2 SORT (JOIN)
4 3 TABLE ACCESS (FULL) OF 'T2'
5 2 SORT (JOIN)
6 5 TABLE ACCESS (FULL) OF 'T1'
想想也有道理,Oracle先對OWNER欄位進行排序,進行MERGE JOIN連線後,再對OBJECT_TYPE欄位進行GROUP BY。
如果使用HASH_JOIN提示,Oracle也可以得到執行結果:
SQL> SET AUTOT TRACE EXP
SQL> SELECT /*+ USE_HASH(T2) */ USERNAME, OBJECT_TYPE, CN
2 FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE), T2
3 WHERE USERNAME = OWNER
4 AND USERNAME LIKE 'SYS%';
執行計劃
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=54 Card=1467 Bytes=76284)
1 0 SORT (GROUP BY) (Cost=54 Card=1467 Bytes=76284)
2 1 HASH JOIN (Cost=45 Card=1467 Bytes=76284)
3 2 TABLE ACCESS (FULL) OF 'T2' (Cost=2 Card=2 Bytes=48)
4 2 TABLE ACCESS (FULL) OF 'T1' (Cost=42 Card=5867 Bytes=164276)
不過這個SQL也很有意思,只需要將上面的USERNAME改成OWNER,就會報錯:
SQL> SELECT OWNER, OBJECT_TYPE, CN
2 FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE), T2
3 WHERE USERNAME = OWNER
4 AND USERNAME LIKE 'SYS%';
WHERE USERNAME = OWNER
*
第 3 行出現錯誤:
ORA-00979: 不是 GROUP BY 表示式
這時即使加上HINT也不行:
SQL> SELECT /*+ USE_HASH(T2) */ OWNER, OBJECT_TYPE, CN
2 FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE) T1, T2
3 WHERE USERNAME = OWNER
4 AND USERNAME LIKE 'SYS%';
WHERE USERNAME = OWNER
*
第 3 行出現錯誤:
ORA-00979: 不是 GROUP BY 表示式
這個問題在10R2中只能透過RULE方式再現,透過使用USE_MERGE和USE_HASH提示已經無法再現了:
SQL> CONN TEST/TEST@TESTZJ
已連線。
SQL> SELECT * FROM V$VERSION;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for Linux: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
SQL> CREATE TABLE T1 AS SELECT * FROM DBA_OBJECTS;
表已建立。
SQL> CREATE TABLE T2 AS SELECT * FROM DBA_USERS;
表已建立。
SQL> SELECT USERNAME, OBJECT_TYPE, CN
2 FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE), T2
3 WHERE USERNAME = OWNER
4 AND USERNAME LIKE 'SYS%';
FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE), T2
*
第 2 行出現錯誤:
ORA-00979: 不是 GROUP BY 表示式
SQL> SET AUTOT ON EXP
SQL> SELECT /*+ RULE */ USERNAME, OBJECT_TYPE, CN
2 FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE),
3 WHERE USERNAME = OWNER
4 AND USERNAME LIKE 'SYS%';
USERNAME OBJECT_TYPE CN
------------------------------ ------------------- ----------
SYS JOB 4
SYS LOB 95
SYS RULE 4
SYS TYPE 933
.
.
.
SYSTEM INDEX PARTITION 64
SYSTEM TABLE PARTITION 53
已選擇53行。
執行計劃
----------------------------------------------------------
-------------------------------------
| Id | Operation | Name |
-------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | SORT GROUP BY | |
| 2 | MERGE JOIN | |
| 3 | SORT JOIN | |
|* 4 | TABLE ACCESS FULL| T2 |
|* 5 | SORT JOIN | |
|* 6 | TABLE ACCESS FULL| T1 |
-------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - filter("USERNAME" LIKE 'SYS%')
5 - access("USERNAME"="OWNER")
filter("USERNAME"="OWNER")
6 - filter("OWNER" LIKE 'SYS%')
SQL> SELECT /*+ USE_MERGE(T2) */ USERNAME, OBJECT_TYPE, CN
2 FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE), T2
3 WHERE USERNAME = OWNER
4 AND USERNAME LIKE 'SYS%';
FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE), T2
*
第 2 行出現錯誤:
ORA-00979: 不是 GROUP BY 表示式
SQL> SELECT /*+ USE_HASH(T2) */ USERNAME, OBJECT_TYPE, CN
2 FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE), T2
3 WHERE USERNAME = OWNER
4 AND USERNAME LIKE 'SYS%';
FROM (SELECT OWNER, OBJECT_TYPE, COUNT(*) CN FROM T1 GROUP BY OBJECT_TYPE), T2
*
第 2 行出現錯誤:
ORA-00979: 不是 GROUP BY 表示式
看來雖然Oracle10g的CBO已經修正了這個問題,但是RBO中依然存在,而且在Metalink中並沒有看到類似的問題描述,懷疑是CBO最佳化器的升級使得這個bug不可能在新版中再現,而並非是Oracle有意去修正這個問題。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-136135/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 缺少GROUP BY表示式可以順利執行的問題(二)
- GROUPBY 和開窗函式執行順序的問題函式
- mysql order by 和 group by 順序問題MySql
- sql中的or與and的執行順序問題SQL
- 關於defer執行順序問題
- SQL語句中的AND和OR執行順序問題SQL
- ajax回撥函式執行順序帶來的同步非同步問題函式非同步
- SQL中rownum和order by的執行順序的問題SQL
- C++輸出流cout的執行順序問題C++
- 【Oracle】where條件執行順序(上篇的問題延伸)Oracle
- java正規表示式之 groupJava
- connect by與where條件執行順序問題
- 1.自執行函式表示式函式
- js解惑-函式執行順序JS函式
- 南大通用GBase 8s_GROUP BY支援標量函式和表示式問題詳解函式
- await會阻塞其所在表示式中後續表示式的執行AI
- JS中使用EL表示式的問題JS
- Java公式:如何執行字串表示式?!Java公式字串
- js 立即執行函式表示式介紹JS函式
- 讓quake3在linux下順利執行(轉)Linux
- js基礎進階–promise和setTimeout執行順序的問題JSPromise
- group by 排序問題排序
- 多個執行緒順序列印問題,一網打盡執行緒
- unittest.TestCase中測試用例執行順序問題
- Lcust 分散式執行時的引數化問題分散式
- PG 中表示式的計算順序
- IIFE (Imdiately Invoked Function Expression 立即執行的函式表示式)FunctionExpress函式
- 執行JPetStore的問題
- crontab的執行問題
- JavaScript 立即執行函式表示式 ( IIFE ) 用例JavaScript函式
- 詳解javascript立即執行函式表示式(IIFE)JavaScript函式
- 【odoo】【知識點】生成pdf檔案時缺少樣式的問題Odoo
- function.procedure函式下的過程執行問題Function函式
- 關於執行緒插入函式如何用的問題執行緒函式
- JavaScript的執行順序JavaScript
- [BUG反饋]public function group() 方法缺少網頁標題賦值Function網頁賦值
- Python執行緒專題10:queue、多執行緒按順序執行Python執行緒
- 關於觸發器在行級和語句級的執行順序問題觸發器