如何編寫更好的SQL查詢 終極指南 第三部分

2021-09-05 08:06:39 字數 2184 閱讀 1266

本次我們學習《如何編寫更好的sql查詢》系列的最後一篇文章。

通過前兩篇文章,我們已經對查詢計畫有了一定了解。接下來,我們還可以借助計算複雜度理論,來進一步深入地挖掘和思考效能的提公升。理論電腦科學這一領域聚焦於:根據難度來對計算問題進行分類。這些計算問題可以是演算法問題,也可以是查詢問題。

對於查詢,我們可以不按照難度進行分類,而是按照執行查詢並得到結果所需的時間來進行分類。這種方式也被稱為按照時間複雜度進行分類。

使用大o符號,可以根據輸入的增長速度來表示執行時間,因為輸入可以任意大。大o符號不包括係數和低階項,以便可以專注於查詢執行時間的重要部分:增長率。使用這種方式時,會丟棄係數和低階項,時間複雜度是逐漸描述出的,這意味著輸入會變為無窮大。

在資料庫語言中,複雜性衡量了查詢執行時間的長短。

請注意,資料庫的大小不僅隨著表中儲存資料的增加而增加,資料庫中的索引也會影響資料庫大小。

執行計畫定義了每個操作所使用的演算法,這也使得每個查詢的執行時間可以在邏輯上表示為查詢計畫中資料表大小的函式。換句話說,可以使用大o符號和執行計畫來估算查詢的複雜性和效能。

在下面的小結中,我們將會了解四種型別的時間複雜度概念。

通過這些示例,可以看到查詢的時間複雜度會根據執行的查詢內容不同而有所不同。

對於不同的資料庫,需要考慮不同的索引方式、不同的執行計畫和不同的實現方式。

因此以下所列出的時間複雜度概念非常普遍。

有一種查詢演算法,不論輸入的大小如何,都需要相同的時間來執行,這種方式就是恆定時間查詢。這些型別的查詢並不常見,下面是乙個例子:

select top 1 t.*

from t

這種演算法的時間複雜度是乙個常數,因為只是從表中選擇任意一行。因此,時間長度與表的大小無關。

如果乙個演算法的時間執行與輸入大小成正比,那麼演算法的執行時間會隨著輸入大小的增加而增加。對於資料庫,這意味著查詢執行時間與表大小成正比:隨著表中資料行數的增加,查詢時間也會相應增加。

乙個示例就是在非索引列上使用where子句進行查詢:這就需要使用全表掃瞄或順序掃瞄,這將導致o(n)的時間複雜度。這意味著需要讀取表中的每一行,以便找到正確id的資料。即使第一行就查詢到了正確的資料,查詢還是會對每一行資料進行讀取。

如果沒有索引,那麼這個查詢的複雜度為o(n)i_id:

select i_idfrom item;
與線性執行時間密切相關的是,所有線性執行計畫的時間總和。下面是一些例子:

對於巢狀連線,複雜度通常為o(mn)。當乙個或兩個表非常小(例如,小於10個記錄)時,這種連線方式特別有效。

請記得:巢狀連線是將乙個表中的每個記錄與另乙個表中的每個記錄進行比較的連線方式。

如果演算法的執行時間與輸入大小的對數成比,則演算法被稱為對數時間演算法; 對於查詢,這意味著執行時間與資料庫大小的對數成正比。

執行索引掃瞄(index scan)或聚集索引掃瞄的查詢計畫時間複雜度,就是對數時間。聚集索引是索引的葉級別包含表的實際資料行的索引。聚集與其他索引非常相似:它是在乙個或多個列上定義的。這也形成了索引主鍵。聚集主鍵是是聚集索引的主鍵列。聚集索引掃瞄是聚集索引中rdbms從頭到尾一行一行讀取的基本操作。

以下的示例中存在乙個i_id的索引,這也導致o(log(n))的複雜度:

select i_stockfrom itemwhere i_id = n;
如果沒有索引,則時間複雜度是o(n)。

如果演算法的執行時間與輸入大小的平方成正比,則演算法被稱為對數時間演算法。對於資料庫,這意味著查詢的執行時間與資料庫大小的平方成正比。

具有二次時間複雜度的查詢的示例如下:

select *

from item, authorwhere item.i_a_id=author.a_id

最小複雜度為o(n log(n)),但是基於連線屬性的索引資訊,最大複雜度會是o(n ^ 2)。

下圖是一張根據時間複雜度來估算查詢效能的圖表,通過圖表可以檢視每個演算法的效能表現。

可以從以下方面衡量查詢計畫和時間複雜性,並進一步調優sql查詢:

《如何編寫更好的sql查詢》教程的所有內容就介紹到這裡,希望通過本教程的介紹,能夠幫助大家編寫出更好、更優的sql查詢。

如何編寫更好的SQL查詢 終極指南 第三部分

本次我們學習 如何編寫更好的sql查詢 系列的最後一篇文章。通過前兩篇文章,我們已經對查詢計畫有了一定了解。接下來,我們還可以借助計算複雜度理論,來進一步深入地挖掘和思考效能的提公升。理論電腦科學這一領域聚焦於 根據難度來對計算問題進行分類。這些計算問題可以是演算法問題,也可以是查詢問題。對於查詢,...

如何編寫更好的SQL查詢 終極指南 第三部分

本次我們學習 如何編寫更好的sql查詢 系列的最後一篇文章。通過前兩篇文章,我們已經對查詢計畫有了一定了解。接下來,我們還可以借助計算複雜度理論,來進一步深入地挖掘和思考效能的提公升。理論電腦科學這一領域聚焦於 根據難度來對計算問題進行分類。這些計算問題可以是演算法問題,也可以是查詢問題。對於查詢,...

使用正規表示式編寫更好的SQL

oracle database 10g 的乙個新特性大大提高了您搜尋和處理字元資料的能力。這個特性就是正規表示式,是一種用來描述文字模式的表示方法。很久以來它已在許多程式語言和大量 unix 實用工具中出現過了。oracle 的正規表示式的實施是以各種 sql 函式和乙個 where 子句操作符的形...