SQL語句的優化過程(2)

2021-06-08 17:35:34 字數 4373 閱讀 8650

上述語句訪問表

tb_user_grant

中10%

的資料。

連線(join)方法

連線是指從乙個或者多個表中檢索資料。oracle主要有3種連線方法:巢狀迴圈連線(nested loop joins)、雜湊連線(hash joins)和排序合併連線(sort merge joins)。在select語句中,連線方法至關重要,它直接影響查詢的效能。

巢狀迴圈連線(nested loop joins)

巢狀迴圈連線適合處理小量資料。oracle首先選擇一張表作為連線的驅動表(driving table),這張表也被叫做外部表(outer table),其他表被當做內部表(inner table),內部表也叫被驅動表。對於驅動表中的每行,oracle將訪問內部表中的所有行。

巢狀迴圈連線可以快速返回查詢結果的前幾行,這是因為,它不需要等到全部迴圈結束再返回結果集,而是不斷地返回查詢的結果,也就是語句邊執行邊返回結果。

雜湊連線(hash joins)

雜湊連線用於處理大資料量的資料集(特別是乙個大表和乙個小表的連線)。oracle從兩個表中選擇乙個較小的表,按照連線關鍵字(join key),在記憶體中建立雜湊表(因此雜湊表中較小的表適合放在記憶體中),然後,oracle掃瞄另外乙個表(大表),從中發現可以被連線的行。

排序合併連線(sort merge joins)

排序合併連線的原理是,兩個表先按照連線關鍵字(joinkey)進行排序,再把排好序的兩個結果集合並在一起。所以,如果其中乙個結果集已經排好序,"排序合併連線"方式的速度將比"雜湊連線"方式快。

4.統計資訊的解釋

通過autotrace,我們不僅可以獲得sql語句的執行計畫,還可以獲得sql語句的統計資訊。接下來,我們將對sql語句的統計資訊進行解釋。

0  recursive calls--

遞迴呼叫的次數。

0  db block gets--

當前塊(current block)被請求的次數,當前塊是指未被修改過的塊。

32  consistent gets--

對塊一致性讀的請求次數,一致性讀涉及讀回滾段。

0  physical reads--

從磁碟讀的塊的數量。

0  redo size--

產生的回滾資料的大小,單位是位元組(bytes)。

7748  bytes sent via sql*net toclient--

後台程序傳送給客戶端的資訊量大小,單位是位元組。

603  bytes received via sql*netfrom client--

客服端發給資料庫伺服器的資訊量的大小,單位是位元組。

19  sql*net roundtrips to/fromclient--oracle net

傳送和接受的資訊數量,單位是條。

0  sorts (memory)--

記憶體排序的次數。

0  sorts (disk)--

磁碟排序的次數。

256  rows processed--

處理資料的行數(通常指返回的記錄數)。

5.sql優化的目標

有的朋友說,減少一條sql語句的執行時間是我們優化sql語句的目標。對,沒錯,但是在大部分情況下,我們不能在生產系統中直接執行除錯中的sql語句,以獲得該語句的執行時間。不過,在不真正執行sql語句的情況下,我們有一些衡量指標,這些指標可以幫助我們衡量優化後的sql語句是否真的比以前的sql語句更加高效。因此,根據經驗,筆者總結sql調整的目標是:

減小consistent gets的值

減小db block gets的值

減少排序,尤其磁碟排序sorts(disk)

減少遞迴呼叫(recursive calls)

減小執行代價(cost)

要實現sql調整的目標,我們需要採取諸如加索引、改寫sql語句等措施。

知識點索引--執行代價

執行代價與sql語句使用的資源(i/o、cpu、記憶體等)有關。如果一條sql語句使用的資源較多,我們就說該sql語句的執行代價大。執行代價的大小是衡量sql語句是否高效的標準之一,但是,執行代價是乙個相對值。

6.sql優化措施(基本準則)

本節將介紹sql語句優化的措施。sql語句的優化是乙個複雜而循序漸進的過程。在對sql語句實行優化措施之後,我們要檢視衡量sql語句的各項指標是否下降。有的優化措施不僅不能加速sql語句的執行,反而使sql語句的執行更加緩慢。進行sql優化時,我們可以採取下面的措施:

收集統計資訊

重構索引

重構資料

禁用約束和觸發器

盡量使用相同的sql語句

改寫sql語句

收集統計資訊

統計資訊是存放在資料字典中的一系列的資料,它用於精準地描述資料庫和資料庫中的物件(如表、索引)。統計資訊包括:表的統計資訊、列的統計資訊、索引的統計資訊、系統的統計資訊(包括cpu和i/o的)。統計資訊能夠幫助優化器選擇最好的執行計畫,所以,統計資訊的精確性尤為重要。如果你沒有收集統計資訊或者很長時間沒有重新收集統計資訊(舊的統計資訊不能準確地反映資料變化),都將影響優化器選擇最優的執行計畫。

因為資料庫中的物件和資料在不斷變化,所以我們應該定期收集統計資訊。有以下兩種方法收集統計資訊。

自動收集統計資訊

在預設情況下,oracle啟動了統計資訊的自動收集功能,如果你禁用了統計資訊的自動收集,可以使用下面的命令啟用統計資訊的自動收集。

1.begin   2.

dbms_auto_task_admin.enable(   3.

client_name

=>

'auto optimizer stats collection',  4.

operation

=>

null,   5.

window_name

=>

null);   6.

end; 

自動收集統計資訊會消耗一部分系統資源,如果沒有必要可以關閉該功能。關閉自動收集統計資訊的命令如下所示:

1.begin   2.

dbms_auto_task_admin.disable(   3.

client_name

=>

'auto optimizer stats collection',  4.

operation

=>

null,   5.

window_name

=>

null);   6.

end; 

手動收集統計資訊

如果我們不想啟用"自動收集統計資訊",可以利用包dbms_stats來手工收集統計資訊。包dbms_stats包含如下的過程:

收集索引的統計資訊

1.execute dbms_stats.gather_index_stats('itme','kk'); 

上述命令收集使用者模式itme下的索引kk。

收集表的統計資訊

1.execute dbms_stats.gather_table_stats('itme','studentbook'); 

上述命令收集使用者itme的表studentbook的統計資訊。

收集使用者擁有的所有物件的統計資訊

1.execute dbms_stats.gather_schema_stats('itme'); 

上述命令收集使用者itme擁有的所有物件的統計資訊。

收集資料字典物件的統計資訊

1.execute dbms_stats.gather_dictionary_stats; 

收集資料庫中所有物件的統計資訊

1.execute dbms_stats.gather_database_stats; 

重構索引

重構索引的工作包括以下幾方面:

刪除多餘的索引,以加速dml語句的執行。如果乙個表上的操作是以dml為主,考慮刪除冗餘的dml。

刪除組成索引列中無用的列。因為有的列在where條件中很少使用或者從未使用,這樣的列不僅不利於查詢,可能會反而阻礙dml語句的執行。

改變索引中列的順序,使索引中列的順序和where條件中列的順序相同。

考慮往索引中新增新的列。

重建索引,消除索引中的碎片。

注意:索引不是靈丹妙藥。有時候索引卻會加重系統的負擔。

重構資料

如果資料分布不合理,即使我們再怎麼調整sql語句,效果也只是杯水車薪。資料的分布是否合理將直接影響sql的效能。在此,我們主要討論資料分布的兩項技術。

資料分布的其中一項技術是分割槽(partitioning),理想的分割槽技術是,將乙個大表按照一定的邏輯分成n塊,每塊單獨存放在乙個物理磁碟中,這時候需要n塊磁碟,並在分割槽表上建立相應的索引。

資料分布的另外一項技術是聚簇(cluster)。如果兩個表經常按照某列進行連線(join),則可以把這兩個表放到聚簇中。這項技術使兩個表中的資料物理地存放在一起,減少i/o,加速對兩個表的訪問。

談談SQL 語句的優化技術 2

三 優化sql語句的系統設計原則 僅僅簡化還是不夠。sql語句的優化在系統的設計階段就要通盤考慮。系統設計越合理,需要優化或後期返工的地方就越少。系統邏輯流程如果不合理,那麼常會導致本來需要乙個操作就可以解決的問題卻要作好幾個操作才能實現,反映在資料庫上就是發出過多或過複雜的sql語句。所以資料庫系...

DB2 SQL語句的優化

最近在做一銀行的優化專案,由於正在學習中,所以做的一些筆記 1.sql語句除了引號內的特殊字元,其他的語句都要大寫。2.多表聯查,資料量按從少到多排列,當然第乙個主表通常資料量比較大,因為第乙個表通常為主表,但是從第二個表就要資料量從少到多排列了 如果遇到兩張表的資料一大一小,小表只能跟大表關聯,大...

db2sql語句優化

最經專案中要用到乙個樹形載入結構,由於底層資料有點多,再加上sql語句沒有怎麼優化,所以頁面資料載入的時候特別慢。只查詢底層資料的話就需要七八秒中,後來經過別人的指點從新優化sql後,底層資料的載入查詢控制在了200毫秒以為。現在就貼上我的sql語句,供大家看一下 沒有優化的sql語句 select...