天天看點

Postgresql SQL 優化 --full scan index scan index only 的差別

Postgresql SQL 優化 --full scan index scan index only 的差別

在查詢中一般通過查詢計劃中可以發現如下的一些東西,如 full scan , index scan , index only 這三種對于表通路的方式。

那麼我們的着重對這三個經常看到的執行計劃中對表通路的标簽進行更細緻的了解。

FULL SCAN (sequential scan),明确意思就是就是全表掃描,部分人到這裡其實已經不想在往下看了,但其實我們需要明确一些關于FULL SCAN 的問題,如

什麼時候POSTGRESQL 會對需要通路的表FULL SCAN , FULL SCAN 如果不是對表通路的一個好方法,有什麼方法可以避免FULL SCAN , FULL SCAN 的原理又是什麼。

如果可以寫一段程式來表達FULL SCAN (seq scan) ,可以用如下的邏輯

From table block in a table Loop
               read block;
               for each row in block Loop
                        if  row = condition
                             go to cache
                         end if;
                end loop;
       End loop;
           

複制

如果這裡讀入一行的成本是 1 ,判斷一行的成本是2 ,一個100行的表的成本可以記錄為 (1+2)* 100 = 300

這顯然是一個不怎麼好的算法,但确實是一個兜底的資料 FETCH 的方案。這裡對于資料的讀取并不是實際意義上的行,在實體層面讀入記憶體的資料是以塊,資料塊或者資料頁面的方式讀入到記憶體。

FULL SCAN (sql scan)最大的問題是,沒有經過篩選的将資料全部讀入記憶體後,在進行資料是否符合條件的鑒别處理,這裡大量的浪費了磁盤的I/0與記憶體的資源,并且在比對的過程中也大量的浪費了CPU的計算資源。

Postgresql SQL 優化 --full scan index scan index only 的差別

可以看到采用table scan 的資料處理方式,cost 前置需要的消耗是0,rows 後面的數字是整體的表的總行數。

Index scan , 對于Full scan 來說大部分人都是明白其中的原因和原理,index scan 的成因和原理能說的明白的開發人員就比較少了。

首先我們要明确的一點,如果單表的通路中,FULL SCAN 的速度很快,快到根本不需要想辦法用其他的方法來提高資料的通路速度, 在這樣的基礎上我們是根本不用使用索引,或者這類辦法,因為本身索引就是一個 備援的,占用更多存儲空間的,重複的資料,而索引之索引誕生,主要有兩個因素

1 算法,一種算法可以快速的對大量的資料進行快讀的定位

2 基于這樣的算法,需要對資料的存儲結構進行重新的定義

這是我個人對于索引出現的了解,索引本身最大的意義就是快速定位資料。一般我們提到索引,腦子裡面想到的就是 BTREE 或基于這類凡是存在的資料存儲結構和快速定位的算法。

除此以外,索引的出現還帶有另一個因素就是條件,一個SQL 如果利用索引是必須要有條件的,此時我們的SQL 需要添加新的成員了。

下面就是一個典型的例子,添加索引和不添加索引的對比,可以對比cost ,明顯添加的索引以後的 index scan 效率要比不添加索引的高。

Postgresql SQL 優化 --full scan index scan index only 的差別

索引本身的功能就是要快速的找到資料,通過索引中存儲的資料的實體位址及指針,将需要尋找的資料在傳回,此間需要兩次,1 通過索引确定實體位址,2 根據實體位址去原來的表中将資料提取。

一般來說,通過index scan 來比對的資料必然有幾個特性

1 搜尋的資料與原表中所有的資料相比,占比極少

2 查詢中的字段并不全包含在索引中

3 Index only scan

Index only scan 本身是在基于上面的基礎上,在滿足條件2 ,也就是所查詢的資料全部在索引中可以提供,而不必在傳回到原表中,這樣查詢的方式好在每個記錄不用在進行重定向,在提取的過程,從下圖也可以看到,COST 直接降了25%,對于回表的操作的消耗,想必這裡大家會有一個感性的認識。

Postgresql SQL 優化 --full scan index scan index only 的差別

這裡我們做一個粗略的比較,看看FULL SCAN , INDEX SCAN , INDEX ONLY SCAN 之間的在COST 上的差別。

我們就用上圖中的COST 做一個參考,數值并不是非常嚴謹,這裡僅僅做一個粗略的說明。

這裡補一下沒有索引查詢時的COST值

Postgresql SQL 優化 --full scan index scan index only 的差別
Postgresql SQL 優化 --full scan index scan index only 的差別

是以上面的資料也給大家一個感受,就是如果一個查詢缺少索引,在添加索引後,感官的性能提升都是幾十倍,上百倍。