oracle執行計劃解釋


         一.相關概念
                1·rowid,僞列:就是系統自己給加上的,每個表都有一個僞列,並不是物理存在。它不能被修改,刪除,和添加,rowid在該行的生命週期是唯一的,如果向數據庫插入一列,只會引起行的變化,但是rowid並不會變。
                2·recursive sql概念:當用戶執行一些SQL語句時,會自動執行一些額外的語句,我們把這些額外的SQL語句稱爲“recursive calls” 或者是“recursive sql statement”,當在執行一個DDL語句時,Oracle總會隱含的發出一些Recursiv sql語句,用於修改數據字典,如果數據字典沒有在共享內存中,則就執行“resursive calls”,它會把數據字典從物理讀取到共享內存。當然DML和select語句都可能引起recursive SQL。
                3·row source 行源:在查詢中,由上一操作返回的符合條件的數據集,它可能是整個表,也可能是部分,當然也可以對2個表進行連接操作(join)最後得到的數據集
                4·predicate:一個查詢中的where限制條件
                5·driving table 驅動表:該表又成爲外層表,這個感念用於內嵌和HASH連接中,如果返回數據較大,會有負面影響, 返回行數據較小的適合做驅動表
                6·probed table 被探查表:該表又稱爲內層表,我們在外層表中取得一條數據,在該表中尋找符合連接的條件的行。
                7·組合索引(concatenated index)由多個列組成的索引,在組合索引中有一個重要的概念,就是引導索引,
                        create index idx_tab on tab(col1,col2,col3),              
                        indx_tab則稱爲組合索引,
                        col1則稱爲引導列
                  在查詢條件where後,必須使用引導索引,纔會使用該組合索引
                8.可選擇性(selectivity)比較一下列中唯一鍵的數量和表中的行數,就可以判斷該列的可選擇性。 如果該列的“唯一鍵的數量/表中的行數”的比值越接近1,則該列的可選擇性越高,該列就越適合創建索引,同樣索引的可選擇性也越高。在可選擇性高的列上進 行查詢時,返回的數據就較少,比較適合使用索引查詢。


        二.Oracle訪問數據的存取方法
                1.全表掃描(Full tabel scans,FTS)
爲了實現全表掃描,Oracle讀取數據庫中的每一行,並檢查每一行是否滿足語句的where限制條件一個多塊讀操作,可以使io能讀取多塊數據塊。減少了IO次數,提高了系統的吞吐量。在多塊讀的方法的使用下,可以高效的實現數據庫全表掃描,而且,中有在全表掃描的情況下,在可以使用多塊讀的方法。在這個種訪問模式下,數據塊只讀一次。
        【注意】
         使用FTS的前提是,在較大的表中,不建議使用FTS,除非取出的數據較多,超過總量的5%-10%,或者使用並行查詢時
                2.通過rowid的表存取
                        行的ROWID指向了該行的數據文件,數據塊,以及在數據塊中的位置,使用rowid能快速的定位到要取得數據的行上,在Oracle中,這是取得單行最快的方式。
         【注意】
                該存取方法,不會用到多塊讀操作,一次IO只能讀取一個數據塊。
                3.索引掃描(index scan 和 index lookup)
                        索引掃描時通過index查找到對應行的rowid,然後通過rowid從數據庫中得到具體的數據。該方法分爲兩個步驟,
                        (1)掃描索引得到得到rowid
                                說明:索引中不止儲存着索引值,還存放的行的rowid
                        (2)通過rowid得到表中的數據
                        【注意】
                         1.由於索引經常使用,因此絕大多數都Cache到內存當中,所以第一步通常是邏輯IO,即數據可以從內存中取得
                        2.但是對第二步來說,如果數據比較大,就不可能存放在內存,因此是個物理操作,是極其耗時間的,因此,從大表中
                        進行索引掃描,如果數量大於總數的5%-10%,則效力會下降很多
                        3.如果索引的數據都能在內存中能找到,就可以避免第二步操作,避免了不必要的IO。效力會很高。
                        4.如果SQL語句會對索引排序,因爲索引已經預先排好了序,索引在執行計劃中不需要在對索引排序。根據索引的類型與where限制條件的不同,有4種數據類型的索引
                        1.唯一索引(index unique scan)
                        通過唯一索引查找一個數值,通常是rowid,如果表中存在unique,或者是primary key的話,Oracle通常實現唯一索引;
                        2.索引範圍掃描(index range scan)
                                如果要取得多行數據,通常在唯一索引上加上範圍操作,例如(>,<)
                                *使用index rang scan的三種情況
                                (a)在唯一索引上有where條件篩選
                                (b)在組合索引上,使用部分列進行查詢,導致查詢出多行
                                (c)對非唯一 索引列進行的任何查詢
                      3.索引全掃描(index full scan)
                      與全表掃描想對應的就是全索引掃描,它必要保證要取得的數據都從索引中直接得到
                                例:
                   Index BE_IX is a concatenated index on big_emp (empno, ename)
                   SQL> explain plan for select empno, ename from big_emp order by empno,ename;
                   4.索引快速掃描(index fash full scan)
                   索引快速掃描和index full scan相似,不會對查詢出的數據進行排序。

      
        三.表之間的連接
                 根據row source連接的條件不同,可以分爲等值連接(where a.col3=b.col4)非等值連接(where a.col3>b.col4)外連接 (where a.col3=b.col4(+))
                1.典型的連接類型
                        (a)排序--合併連接(sort merge join,SMJ)
                        (b)嵌套循環(nested loops,NL)
                        (c)哈希連接(hash join,)
                A.排序--合併連接
                        1)首先生成row source1需要的數據,讓後對連接關聯的列進行排序。
                        2)然後生成row source2需要的數據,然後對這些數據按照與row socurce1相對應的操作關聯列進行排序。
                        3)將兩邊排好序的數據進行合併操作,將2個row source按照連接條件連接起來。
                        [注意]
                        ·.如果row source已經在關聯上列上被排序,那個連接操作就不會執行sort操作,將大大的提高效率,因爲排序時極其 消耗資源的,預先被排序的row source包括索引,或者已經排好序的列。
                        ·.排序是非常耗時的操作,尤其是大表,基於這個原因,SMJ通常不是一個好的解決辦法,如果排序的工作早已做好那將極大的提高效率
                          ·.對於非等值連接,這種連接方式的效率是比較高的。
                B.嵌套循環。
                      在連接有驅動表的概念,實際上連接過程就是2層嵌套循環,外層表越小越好。
                        [執行原理]
                        從內部表來看,需要得到外層表的每一行,去匹配內部表的所有行,因此保持外部表儘可能小,和高效率訪問內部表,是連接性能的關鍵。
                        [優點]
                         nested loops可以返回已經連接的行,而不必等待所有的行連接完,因此能快速響應,特別適合用在需要快速響應的語句中。
                     C.hash join
                        較小的row source用來構建hash table和bitmap,而第二個用來被hansed,並與第一個生成的hash table進行匹配。
                        bitmap用來作爲一種較快查詢的方法,用來檢查hash table是否有匹配的行,特別在表大的情況下,不能容納在內存中,這個連接方法非常有效。這個鏈接,也有驅動表的概念,有來構造hash table,bitmap的表叫驅動表,如果被 構建的hash table,bitmap都能容納在內存中,這個效率非常高。
                        【注意】
                        1) 要使哈希連接有效,需要設置HASH_JOIN_ENABLED=TRUE,缺省情況下該參數爲TRUE,另外,不要忘了還要設置 hash_area_size參數,以使哈希連接高效運行,因爲哈希連接會在該參數指定大小的內存中運行,過小的參數會使哈希連接的性能比其他連接方式還要低。
                        2)只能用於等值連接。
                        3)在2個較大的row source之間連接時會取得相對較好的效率,在一個row source較小時則能取得更好的效率。
      

         解釋結果:
                1.AND-EQUAL 該步驟具有兩個或更多個子步驟,每一個子步驟返回一系列的ROWID.AND-EQUAL操作選擇的是索引子操作返回的rowid      
                2.BITMAP
                        conversoin to rowids --將位圖從位圖索引轉換成可以用於提取實際資料的一系列的ROWID
                        conversoin from rowids --將一系列的ROWID轉換成位圖表示
                        conversoin count --對位圖的行數進行統計
                        index single scan --爲單個索引提取位圖
                        index range scan --返回的位圖是一定範圍的關鍵值
                        index full scan --掃描整個位圖索引
                        MERGE        --合併兩個位圖,並作爲一個位圖返回結果
                        Minus --該操作是merge的相反操作,而且可以具有兩個或3個子操作並返回位圖
                                第一個子操作返回的位圖用作起點,第一個位圖減去第二個位圖中提供所   有行。如果第二個位圖爲空,那麼所有的null列也將被減去。
                        or  --將兩個位圖作爲輸入
                3.connect by --分層提取行,因爲查詢採用了CONNECT BY C從句
                4.concatenaction --合併多個行集爲一行。
                5.count --計算從表中選擇的行數
                        stopkey --計算的行數被查詢語句中的where 中的 rownum所限制
                6.filter --將一系列的行數作爲輸入,並過濾到where從句查詢而得到的結果
                7.first row --提取查詢結果集的第一行
                8.for udpate -- 爲提取的行加鎖。
                9.hash join --使用散列連接法連接兩張表
                10.index
                        unique --從索引中查找唯一值
                        range scan --從一定範圍中查找,是按照升序的方式
                        range scans desc --掃描行在一定範圍之內,但是是按照降序的方式
                11.inlist iterator --在in謂詞中爲一個值執行一次或者多次操作
                13 intersection --將兩個結果集合併成一個集,並返回在它們之間出現的共同的值
                14 merger join --提供共同值,用來連接兩個結果集的結果。是內連接
                         output --外
                         anit --反
                         seml --半
                15 nested loops --該操作涉及到2個子操作,第一操作個返回一個行集,被用於行集中的每一行,執行第二個子操作。
                         output --用於執行外部套嵌套循環
                16 partition [分區] --執行一或者多個分區操作,partition-start,partition-stop將提供分區的範圍
                                singnal  --顯示操作將在單個分區上執行
                                iterator        --在許多個分區中執行
                                all  --顯示操作將在所有分區上執行
                                inlist --顯示操作在分區上執行,並用IN謂詞驅動
                17 projection --採用多個查詢作爲輸入,並返回單個記錄集。常和intersection,minus, unqie使用      
                18 sort
                        aggregate --在行集上採用分組函數
                        unique  --對行集排序,去掉重複的行
                        join  -- 和merger相同
                        group up -- 分組排序
                        orday by --按照orday by進行排序
                19 table access
                                full --顯示指定表中的所有行
                                cluster --與特定索引鍵進行匹配的所有行
                                hash  --散列
                                by rowid --顯示oracle表將從rowid提取
                20 unqie 顯示兩個集,並去掉重複行
                21 view 產生視圖,並返回結果行集。

原文鏈接:https://www.iteye.com/topic/586256

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章