1. 程式人生 > >Oracle中的查詢轉換簡介(上)

Oracle中的查詢轉換簡介(上)

Oracle查詢轉換的概念:
Oracle在解析目標sql時可能會對其對其做等價改寫,目的是為了更高效的自行目標sql,即Oracle可能會將目標改寫成語義上完全等價的但執行效率更高的形式。

Oracle查詢轉換的型別有如下:

子查詢展開
檢視合併: 簡單檢視合併 外連線檢視合併 複雜檢視合併
星型連線轉換
連線謂詞推入
連線因式分解
表擴充套件
表移除
Oracle處理sql中語句中IN:
In List Iterator
In List Expansion /OR Expansion
In List Filter
對IN做子查詢展開、檢視合併

以下分別簡單解釋:

子查詢展開:
優化器處理還有子查詢的目標sql的一種優化手段。它是指不再將子查詢作為一個單獨的整體來處理,而是將其轉化為自身和外部查詢之間等價的表連線。
分為兩種情況:一種是將子查詢展開; 一種是不拆開但是把子查詢轉為一個內嵌的檢視,再和外部的表,檢視做連線。

如果不做子查詢展開,那麼通常的執行計劃是,這個子查詢在目標sql的最後一步才執行,並且會走filter型別的執行計劃。

Oracle能否做子查詢展開取決下面兩個條件:
子查詢展開所對應的sql在語義上應該和原sql完全等價。否則便不能進行子查詢展開(這是理所當然的條件)
對於子查詢不展開,而轉為一個內嵌試圖的子查詢展開,只有當經過子查詢展開後的等價改寫sql的成本值小於原sql的成本值,才會進行此類的子查詢展開。

 對於子查詢展開的第一種情形,Oracle始終會對其進行子查詢展開,而不管經過子查詢展開後的sql的成本值是否小於原sql的成本值。

Oracle並不對所有的子查詢進行子查詢展開,它還有前提條件的,也就是滿足了這些條件,才可能考慮進行子查詢展開。

Oracle資料庫裡子查詢前的where條件如果是如下這些條件之一,那麼這種型別的目標sql在滿足了一定條件之後就可以做子查詢展開:

single-row (即 = < > <= >= 和<>)
exists
not exists
in
not in
any
all

select t.userid, wm_concat(r.standno) as standno
          from TB_PRODUCTCTRL_USERTASKINFO t, (select * from TB_PRODUCTCTRL_LINETASKINFO where ownerworkshop = #{workshop} ) r
         where t.taskclose = 'N'
           and t.taskstatus = 'N'
           and trunc(t.senddate, 'dd') > sysdate - 2
           and r.soflseqnr = t.tasksoflseqnr
         group by t.userid

上述sql裡面也有子查詢,但是Oracle不會進行子查詢展開,因此子查詢會以filter執行計劃的方式,在最後一步出現。

這裡寫圖片描述

下面這樣寫就可以進行子查詢展開了, 下面的sql去掉了這個值 wm_concat(r.standno) as standno,是為了方便說明子查詢展開限制條件的問題。 這個sql在業務中是不需要子查詢就可以完成的。

select t.userid
          from TB_PRODUCTCTRL_USERTASKINFO t 
         where t.taskclose = 'N'
           and t.taskstatus = 'N'
           and trunc(t.senddate, 'dd') > sysdate - 2
           and t.tasksoflseqnr in (select r.soflseqnr from TB_PRODUCTCTRL_LINETASKINFO r where ownerworkshop = 'chang')
         group by t.userid

這裡寫圖片描述

檢視合併:
檢視合併是Oracle處理帶有檢視的sql的一種優化手段。它的基本原理也是不再將視做為一個單獨的檢視來處理,而是將其拿出來和外部查詢合併。
檢視合併分為三種類型:簡單檢視合併,外連線檢視合併,複雜檢視合併。對於簡單檢視合併,只要符合進行簡單檢視合併的條件,Oracle始終會對其做檢視合併,而不管經過檢視合併後的等價改寫sql的成本值是否小於原sql的成本值。對於複雜檢視合併,只有等價改寫後的sql的成本值小於原sql的成本值時,Oracle才會對目標sql進行復雜檢視合併。

Oracle做簡單檢視合併後的等價改寫只是讓優化器有了更多的執行路徑可以選擇,原來的未做簡單檢視合併情形下的執行路徑還是保留了,所以做了簡單檢視合併後等價改寫sql的成本值一定小於等於未做簡單檢視合併的原sql的成本值。

**這個和子查詢展開的第一張情況並不一樣,Oracle始終會做子查詢展開,但是展開後存在成本值大於原sql成本值的情況。**

Oracle進行簡單檢視合併的條件:
檢視定義中
不包括外連線,
不包含distinct group by等聚合函式,
不包含集合運算子:union all union intersect (表是兩個表的交集) minus (A-B)
不包含:connect by子句
不包含: rownum
……

外連線檢視合併:
用來處理使用了外連線,以及檢視定義中不存在distinct group byu等聚合函式的sql。

Oracle做外連線檢視合併的條件:
當目標檢視在和外部查詢的表做外連線時,該目標檢視可以做外連線檢視合併的條件是:
要麼該檢視作為外連線的驅動表。當該檢視作為外連線的被驅動表時,他的檢視定義只能包含一個表。

外連線的驅動表,左連線就是左表,右連線就是右表,也就是不增加null行的表。

複雜檢視合併:

複雜檢視合併就是來處理檢視定義總包含distinct group by的語句。

複雜檢視合併的基本原理就是推遲執行distinct 或者group by。但是推遲執行distinct 或者group by並不一定能提升執行效率,因為可能distinct 或者group by會過濾掉大部分資料。

因為複雜檢視合併並不一定提升Oracle效率的提升,只有當經過複雜檢視合併後等價改寫sql的成本值小於原sql的成本值時,Oracle才會對目標sql執行復雜檢視合併。

相關推薦

Oracle查詢轉換簡介

Oracle查詢轉換的概念: Oracle在解析目標sql時可能會對其對其做等價改寫,目的是為了更高效的自行目標sql,即Oracle可能會將目標改寫成語義上完全等價的但執行效率更高的形式。 Oracle查詢轉換的型別有如下: 子查詢展開 檢視合併

oracle實現擷取字串substr查詢字串位置instr、替換字串replace

 (1)oracle中實現擷取字串:substr substr(string, start_position, [length]) 其中,string是元字串,start_position為開始位

JavaJNI的使用

android immediate 返回值 str byte 文件 field 方式 touch JNI 全稱是 Java Native Interface。是在 Java 和 Native 層(包括但不限於C/C++)相互調用的接口規範。 JNI 在 Java 1.1中正

ORACLE字符集查詢和設定11g

ORACLE字符集查詢和設定(11g) 查詢資料庫字符集select userenv('language') from dual; linux中文字符集/etc/sysconfig/i18n LANG=zh_CN.gb18030 #oracle11g 修改字符集 修改為ZHS16GBKconn

C++筆記 第四十一課 型別轉換函式普通型別--類型別---狄泰學院

如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。 學習C++編譯環境:Linux 第四十一課 型別轉換函式(上)普通型別–>類型別 1.再論型別轉換 標準資料型別之間會進行隱式的型別安全轉換 轉換規則如下: 41-1 有趣的隱式型別轉換 #

C++筆記 第六十四課 C++的異常處理---狄泰學院

如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。 學習C++編譯環境:Linux 第六十四課 C++中的異常處理(上) 1.C++異常處理 C++內建了異常處理的語法元素try…catch… try語句處理正常程式碼邏輯 catch語句處理異常情況 try

全面總結Oracle的分割槽表

何時使用分割槽表 分割槽表是對錶按照規則進行劃分,這個是要根據業務場景來確定的。 建議值 1 大於2G的表 2 分割槽鍵必須反應業務需求,CUDR儘量不要跨分割槽操作 如果通過有效隔離,全表掃描就變成了分割槽掃描,降低IO,但如果已經使用索引,且結果集較小時,做分割槽不一定會

Oracle null判斷並替換空值 ORACLEDECODE的用法例子 Oracle的NVL函式用法 用 ISNULL(), NVL(), IFNULL() and COALESCE() 函式替換空值

  可用 NVL(), IFNULL() ,COALESCE(),DECODE() 函式 1.NVL() 從兩個表示式返回一個非 null 值。語法NVL(eExpression1, eExpression2)引數eExpression1, eExpression2 如果 eExpressio

mysql轉換函式講義

--轉換函式: --to_number(數值型別的字元):將字元轉換為數值 --to_char(數值或者是日期):將數值或者日期轉換為字元 --to_date(日期格式的字元):將字元轉換為日期 ----------------數值和字元的互轉----

軟體工程簡介--個人看法

軟體工程到底是什麼?軟體工程師是做什麼的? 軟體工程本質上是工程,工程在定義上來說是“應用科學方法在成本效益比有效的方式下建造一個機器,以針對性的解決現實世界問題”。 軟體工程的特徵 如果從事前開始分析,有兩個特徵:1)不容易發現,2)不容易處理。

linux裝置樹pinctrl的配置

最近在移植linux,用到kernel版本為3.18.22和4.1.3,在高版本的核心原始碼中用到了裝置樹(device-tree),裝置樹中用到pinctrl的配置,記錄一下。 1、普通設定 在配置串列埠時,pinctrl的配置資訊如下所示: <span st

oracle的函式介紹:nvl函式、decode函式、case when函式、sum函式

最近做專案接觸到的oracle資料庫比較多,經常用到裡面的一些函式,以前的部落格中也介紹過行轉列和列轉行,這次再簡單給大家介紹幾個: nvl() NVL(a,b)就是判斷a是否是NULL,如果不

Android圖片壓縮分析

一、前言 在 Android 中進行圖片壓縮是非常常見的開發場景,主要的壓縮方法有兩種:其一是質量壓縮,其二是下采樣壓縮。 前者是在不改變圖片尺寸的情況下,改變圖片的儲存體積,而後者則是降低影象尺寸,達到相同目的。 由於本文的篇幅問題,分為上下兩篇釋出

工業大資料漫談9:開源工業大資料軟體簡介

        今天真是一個美好的時代,有無數的開源系統可以為我們提供服務,現在有許多開發軟體可以用到工業大資料中,當然很多系統還不成熟,應用到工業中還需要小心,並且需要開發人員對其進行一定的優化和調整。下面就簡單介紹一些開源的大資料工具軟體,看看有哪些能夠應用到工業大資料

CSS進階17—— CSS的文字處理

  CSS能夠在眾多的佈局標準中脫穎而出的制勝手段就是其強大的文字處理能力,比如最"簡單"的盒子邊緣文字即將超出就自動換行的能力在CSS流的概念裡幾乎是天生的,並逐漸成為了行業內的“常規認知”,然而同時代的SVG標準要想讓文字換行,還需要你手動處理一下,對於計算機來說,沒有什麼是與生俱

瀏覽器音訊相容性問題

參考文章:http://blog.csdn.net/www3300300/article/details/17709219 我參考了上面連結的文章,由於這篇文章寫於2013年,目前已經不能滿足需求了。 下面我將把我參考改進後的做法列出來: (由於我們公司只

oracle資料庫查詢小問題

1.問題描述,很多時候我們進行查詢時要使用like關鍵字,MySQL和Oracle中都支援like進行模糊查詢,像這樣, t.name like '%張三%',但是今天忽然發現了一個oracle中和like功能一樣的關鍵字instr,這個關鍵字可以起到和like一樣的作用,

域安全通道實用工具nltest.exe的使用簡介

工具: 此工具在Microsoft Windows NT 4.0資源工具包中可以找到,另外如果你有Windows 2003安裝盤的話,在安裝盤的Support Tools目錄下有安裝Support Tools的一個工具包安裝程式,你安裝此工具包後同樣也有nltest.exe工

2018年中總結工作遇到的問題

年初在一家使用golang的公司待了一段時間,當時抱著一顆學習的心態試圖挑戰一下自己,結果因為自己基礎薄弱,能力不足,沒能堅持下去,但是卻學到了非常多的東西,是一段非常寶貴的工作經歷,這裡記錄一下在工作中遇到的奇奇怪怪的問題,儘量將具體的工作內容剝離出去,記錄問

Android 圖片壓縮分析

歡迎大家前往騰訊雲社群,獲取更多騰訊海量技術實踐乾貨哦~ 作者: shawnzhao 一、前言 在 Android 中進行圖片壓縮是非常常見的開發場景,主要的壓縮方法有兩種:其一是質量壓縮,其二是下采樣壓縮。 前者是在不改變圖片尺寸的情況下,