提升Oracle所需的基礎技能

用了幾年的Oracle,對一些日常的開發和優化技術已經所有耳聞,簡單羅列一些

1:單表的查詢性能

要看數據的量,查詢條件,是否命中主鍵、索引;如果數據量在幾百萬,幾乎不需要考慮;

如果幾千萬到億的數據量,如果不走索引,查詢的性能可想而知;

 

當然查詢記錄的數據量跟整表的數據量對比,如果查詢的結果跟總量對比比較大時,避免全部掃描

如果幾乎相當,全部掃描未必是效率低下。

 

2:多表的查詢性能

需要考慮更多因素

全部掃描訪問方式【全表掃描,或者快速全索引掃描】

索引掃描訪問方式

關注:oracle常用的索引類型

B樹索引:適合數據重複率低的列

位圖索引:適合數據重複率高的列

 

索引掃描機制:

索引範圍掃描,索引唯一掃描,索引全掃描,索引跳躍掃描,索引快速全掃描。

當然索引的掃描離不開索引統計信息:聚簇因子(Clustering factor)的統計信息用來幫助優化器生成使用索引的成本信息。

需要識別索引掃描的場景:

索引唯一掃描:當謂詞中包含使用UNIQUE或PRIMARY KEY索引作爲條件的時候,就會選用索引唯一掃描。

索引範圍掃描:當謂詞中返回一定範圍數據的條件時,就會選用索引範圍掃描---比如<,>,LIKE,BETWEEN

索引全掃描:當沒有謂詞但是所需獲取列的列表可以通過其中一列的索引來獲得,謂詞中包含一個位於索引中非引導列上的條件。

索引跳躍掃描:當謂詞中包含位於索引中非引導列上的條件,並且引導列的值唯一的時候,會選擇索引跳躍掃描。

 

多個表之間的聯接方法,優化器確定如何將多個表連接起來的最佳方法以及最恰當的順序。

多個表之間的查詢,如果沒有指定關聯關係,會隱含式地將多個表之間的數據一一聯接,稱爲笛卡兒聯結。

 

多表連接的方式包括:

嵌套循環聯結:使用一次訪問運算所得到的結構集中的每一行來於另一個表進行對碰;如果結構集的大小是有限的,並且在用來聯結的列上建有索引的話,聯結的效率比較高。

排序-合併聯結:獨立地讀取需要連接的兩張表,對每張表中的數據行(where字句中的數據行)按照聯結鍵進行排序,然後對排序後的數據行進行合併。

排序開支比較大,但是合併的過程較快。

嵌套聯結:

笛卡爾聯結:將兩個表的結果一一相乘。

外聯結:返回一張表的所有行以及另一張聯結表中滿足聯結條件的行數據,通過(+)

 

3:理解SQL的本質

關於集合的,並非類似編程語言是面向過程的

比如:

Union:爲將兩個集合的結構合計起來,但是會去掉重複的行

Union All:則返回所有行,包括重複的行記錄數據

當然Oracle 10G,可以通過HASH Unique運算符來去重重複行

Minus:通常替代NOT Exists,反聯結

Intersect:通常替代EXISTS(半聯結),獲取兩個集合中都存在的數據行集。

 

4:關注SQL的執行計劃

從前面的索引和聯結方式,以及SQL的集合的本質,如果想深入優化數據查詢的性能,必須關注執行計劃

PL/SQL Developer可以清楚的分析執行計劃,或者通過SQLPlus來獲取執行計劃,當然運行前的執行計劃,跟運行後的實際執行情況,會有略微區別。

需要關注:

解釋計劃:通過Explain plan用來顯示優化器爲SQL語句所選擇的執行計劃,一個預期執行計劃

                  包括SQL所引用的表、

                  訪問表的方法

                  對每一對需要聯結的數據源所用的聯結方法

                 按次序列出的所有需要完成的運算

                計劃中各步驟的謂詞信息列表

                對於每個運算,估計出該步驟所要操作的數據行數和字節數

               對於每個運算,計算出成本值

              如果適用,所訪問的分區信息

             如果適用,並行執行的相關信息

可以通過explain plan for (sql).

對應的結果保存在PLAN_TABLE中

dbms_xplan.display函數

一個問題不可忽視:解釋計劃基於適用環境,跟最終運行環境可能存在差異;

不考慮綁定變量的數據類型

不“窺視”綁定變量的值

所以可能導致,解釋計劃跟最終的執行計劃有不同。

執行計劃

學會閱讀的技巧

以及獲取最種的實際的執行計劃

通過V$SQL_PLAN來查看計劃運算,跟PLAN_TABLE類似,但是包括一些如何在庫高速緩存中定位並找出當前所執行語句的列

ADDRESS

HASH_VALUE

SQL_ID

PLAN_HASH_VALUE

CHILD_ADDRESS

CHILD_NUMBER

DBMS_XPLAN

實例:select /*recentsql */ sql_id,child_number,hash_value,address,executions,sql_text from v$sql where parsing_user_id=...

查看相關執行計劃

select /*+ gather_plan_statistics*/ empno,ename from scott.emp where ename='Test';

如果有興趣,可以深入分析DBMS_XPLAN

 

 更多精彩會進一步補充......

 

 

 

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