Oracle Database 12c查詢最佳化器的缺陷-外連線導致結果不準確
Oracle 12c R1目前使用的也是越來越多了,但是在實際的使用中還是有不少的問題。由於所處的行業對準確性比較敏感,而12cR1中的最佳化器確實存在著挺多的坑會導致結果不準確。其中之一就是使用外連線可能會導致結果不正確。
場景還原
建立一張測試表:
往測試表中插入兩條資料:
環境已經準備就緒了,很簡單的場景。然後我們來看看執行下面的這條SQL會發生什麼?
這是一條很簡單的SQL,即時不用執行,我們也能很容易得出SQL的結果是什麼。但是實際的執行結果呢?
no rows!!!真的是no rows,不管執行多少次都是no rows。但是如果我們把最佳化器的特性進行降級:
這個結果才是正確的。
我們簡單梳理下上面這個SQL的幾個特徵:
1、參與外連線的物件中有檢視(p)
2、檢視(p)的結果為空集
3、select選擇中有引用p的列
4、p的列參與外連線(p.maddr)
5、表t1用來和p的列進行連線的列還有額外的選擇條件(t1.addr in)
上述條件剛好觸發了12cR1的BUG 21459392。
解決方法
1、將最佳化器降低: alter session set Optimizer_features_enable = '11.2.0.4';
3、安裝補丁: Patch 21459392
場景還原
建立一張測試表:
- create table BUG.T_BUGTEST_01(ID NUMBER,NAME VARCHAR2(30),ADDR VARCHAR2(100),PHONE VARCHAR2(30),MAIL VARCHAR2(100),AGE NUMBER);
-
insert into BUG.T_BUGTEST_01 values (1,'BUG1','LBS1111111','1234567890','bug1@test.com',4);
-
insert into BUG.T_BUGTEST_01 values (2,'BUG2','LBS2222222','1234567890','bug2@test.com',4);
- commit;
-
select t1.*, p.maddr from bug.t_bugtest_01 t1,
-
(select 'notused' maddr from dual where 1 = 0) p
-
where t1.addr = p.maddr(+) and t1.id = 1
-
and t1.addr in ('LBS1111111','LBS2222222')
- order by t1.addr;
-
SQL> select t1.*, p.maddr from bug.t_bugtest_01 t1,
-
2 (select 'notused' maddr from dual where 1 = 0) p
-
3 where t1.addr = p.maddr(+) and t1.id = 1
-
4 and t1.addr in ('LBS1111111','LBS2222222')
-
5 order by t1.addr;
-
- no rows selected
-
SQL> alter session set optimizer_features_enable = '11.2.0.4';
-
-
Session altered.
-
-
SQL> select t1.*, p.maddr from bug.t_bugtest_01 t1,
-
2 (select 'notused' maddr from dual where 1 = 0) p
-
3 where t1.addr = p.maddr(+) and t1.id = 1
-
4 and t1.addr in ('LBS1111111','LBS2222222')
-
5 order by t1.addr;
-
-
ID NAME ADDR PHONE MAIL AGE MADDR
-
---------- ------------------------------ ---------------------------------------------------------------------------------------------------- ------------------------------ ---------------------------------------------------------------------------------------------------- ---------- -------
- 1 BUG1 LBS1111111 1234567890 bug1@test.com
我們簡單梳理下上面這個SQL的幾個特徵:
1、參與外連線的物件中有檢視(p)
2、檢視(p)的結果為空集
3、select選擇中有引用p的列
4、p的列參與外連線(p.maddr)
5、表t1用來和p的列進行連線的列還有額外的選擇條件(t1.addr in)
上述條件剛好觸發了12cR1的BUG 21459392。
解決方法
1、將最佳化器降低: alter session set Optimizer_features_enable = '11.2.0.4';
2、修改隱含引數: alter system set "_optimizer_ansi_join_lateral_enhance"=false;
3、安裝補丁: Patch 21459392
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13885898/viewspace-2140722/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle Database 12c查詢最佳化器的缺陷-檢視合併會造成查詢結果不準確OracleDatabase
- 為什麼Oracle的外連線寫法不同導致查詢結果不同?Oracle
- 等於NULL的查詢條件導致查詢結果不正確Null
- 連結伺服器查詢導致的阻塞伺服器
- 使用ROWNUM將導致查詢結果集的固化
- pageHelper分頁外掛導致的查詢慢的問題最佳化
- oracle 連線查詢Oracle
- 【Oracle】--連線查詢Oracle
- 詳解表連線順序和連線方式是否影響查詢結果
- 【janes】多表查詢 外連線
- 導致代理IP驗證不準確的四種原因
- oracle 查詢結果的各種格式Oracle
- 【MySQL】order by 結果不準確的問題及解決MySql
- Oracle內連線、外連線、右外連線、全外連線小總結Oracle
- Oracle 左外連線、右外連線、全外連線小總結Oracle
- NAMES.DIRECTORY_PATH配置不當導致無法連線oracleOracle
- Oracle查詢轉換(三)外連線檢視合併Oracle
- oracle連線查詢詳解Oracle
- oracle查詢結果外面新增引號Oracle
- Oracle查詢結果 儲存為XMLOracleXML
- JAVA資料庫處理(連線,資料查詢,結果集返回)Java資料庫
- 水煮oracle31----連線查詢&合併查詢Oracle
- iptables導致無法遠端連線oracleOracle
- MySQL pager和nopager命令--不顯示查詢結果MySql
- 3.DQL資料查詢語言(內連線,外連線,自連線)
- 連線查詢
- mysql查詢結果多列拼接查詢MySql
- DBeaver的sql查詢結果突然不見了,怎麼辦?SQL
- SpringBoot分頁查詢 頁碼問題導致返回結果數量為0Spring Boot
- 【SQL】Oracle的內連線、左外連線、右外連線及全外連線SQLOracle
- oracle 精確查詢和模糊查詢Oracle
- Oracle 內外連線 join 總結Oracle
- Oracle 表連線方式詳解(外連結、內連線、自連線)Oracle
- oracle的查詢最佳化Oracle
- 統計資訊不準確導致執行計劃走了笛卡爾積
- 查詢重寫對全外連線無效
- MYSQL學習筆記23: 多表查詢(自連線內連線+左右外連線)MySql筆記
- 環境變數設定錯誤導致sqlplus 連線不上oracle變數SQLOracle