請記住,全掃描是否為高效的選擇取決於需要訪問的資料區塊個數(IO操作)以及最終的結果集行數(捨棄的百分比)。如上一篇‘全掃描的影響因素之資料在資料區塊中的儲存方式’中例子所示,資料的儲存返回時在最佳化器決策的過程中扮演了重要的角色。此外,全掃描是否為高效的選擇的另一個關鍵因素的捨棄。捨棄的行是那些用過篩選謂語(where條件)來進行驗證,被證明是不符合條件後從最終的結果集中剔除的資料行。
在上一篇的例子中,全表掃描運算必須檢查表中的所有的10000行資料並捨棄其中的9700行,以得出最終的300行結果集。對於每一行所做的檢查就僅僅是篩選謂語id<3。為了執行這個篩選,每一次檢查都會使用CPU,這也就意味著儘管需要訪問的資料區塊數目是有限的,為了完成每一行的檢查篩選仍需要話費相當多的CPU資源,所以,CPU的使用成本也會歸入到全掃描的成本中。
由上可知,所訪問的資料快的數目以及捨棄的數量越大,全掃描的成本也就越高。
上圖展示了上一篇例子中的表2的資料行以及資料區塊的查詢。基於所列出的資料區塊數目,全掃描大約需要訪問155個資料區塊。
隨著時間的推移,新的行被插入到表中使得表更得越來越大,捨棄這麼多的資料行的成本也不斷增加,到一定程度時最佳化器將會自動切換到使用索引掃描運算。
測試:將原來的10000行資料加到1000000行
> 清空表中的舊資料:
delete from seq_scan_store_2
> 修改function:
create or replace function func_seq_scan_2() returns void as $$ begin for i in 1..1000000 loop insert into seq_scan_store_2(sid,name1,name2,name3,name4,name5) values(mod(i,100),'zhansang'||(i/100),'lisi'||(i/100),'wangwu'||(i/100),'zhaoliu'||(i/100),'wangba'||(i/100)); end loop; end $$language plpgsql;
> 插入資料:
select func_seq_scan_2();
> 查看解釋計劃:
通過增加資料已經使最佳化器放棄了全表掃描要使用位元影像索引掃描,
此時的該表全部資料所跨越的資料區塊有11000多個