索引 vs 全表掃瞄

2021-08-21 10:23:45 字數 1962 閱讀 2925

之前我們介紹了第乙個檔案格式:

檔案格式簡介

在這個檔案格式裡,資料沒有排序,順序儲存,我們只提供了查詢所有資料的介面,當我們想進行值過濾時,比如查詢大於10的資料,需要將所有資料遍歷一遍,如果把這個檔案看做乙個只有一列的表,這種查詢方式就叫全表掃瞄。

磁碟的組織結構 碟片->磁軌->扇區。由於碟片是並行操作的,因此可以忽略尋找碟片的時間。所以基本上要找乙個資料需要找到對應的磁軌(類似樹的年輪),再找對應的扇區(一段扇形)。

磁碟效能的主要度量指標有以下幾個:

資料傳輸率:在定位資料之後。就開始將資料從磁碟和記憶體之間傳輸了。這個時間一般每秒幾十mb。

磁碟上的檔案是一塊一塊組織的,這裡的塊(block)是邏輯概念,可能512位元組到幾kb。從磁碟讀資料需要一塊一塊讀。即使你唯讀1byte資料,也會讀一塊。

順序訪問:連續訪問磁碟相鄰的塊。這樣磁碟只需要一次磁碟尋道。

隨機訪問:隨機訪問磁碟不同位置的塊,一般每次唯讀少量資料。這樣磁碟每處理乙個隨機訪問請求就需要一次磁碟尋道。隨機訪問的效率遠低於順序訪問。

硬體:磁碟資料傳輸率記做 t,平均訪問時間記為 s。

資料:乙個包含 n 個資料的資料集,資料是可比較的。資料在磁碟上無序儲存,資料均勻分布。每個資料所佔空間為 x,那麼資料的總大小為 nx。

這張圖表示資料在磁碟上的存放順序:

索引:在資料上建立索引,索引可以看成資料的一種對映,一種表示方式。可以全部放在記憶體中,並且精確定位原始資料。

查詢模式:查詢有過濾條件,假設過濾條件的選擇度為 f,意思是查詢結果集佔總資料量的 f 倍,f 處於 [0,1] 之間。

現在有兩種查詢方式:全表掃瞄、索引。全表掃瞄和索引都是邏輯概念。

全表掃瞄:最簡單的查詢操作。即將資料從磁碟上乙個個讀到記憶體中做過濾,最後返回結果。這種方式的特點是不管資料有沒有用,都先讀出來,磁碟讀取資料總量大,但是seek只有一次。對應磁碟的順序訪問。

黃色表示需要從磁碟讀到記憶體中的資料,全表掃瞄時候就是這樣:

全表掃瞄總耗時 = io耗時 = nx/t

索引:由於磁碟上資料是亂序的,我們建乙個b+樹索引,並在記憶體中維護索引,索引將所有資料排序,並記錄對應的磁碟位置。在查詢時,首先在索引上過濾出所有結果集在磁碟上的位置,再到磁碟上去精確讀取結果集。這種包括少量的磁碟io+大量的 seek。對應磁碟的隨機訪問。

seek耗時:nfs

io耗時:nfx/t

索引查詢總耗時 = seek耗時 + io 耗時 = nfs + nfx/t

接下來看看這些引數,在不考慮更新硬體時,磁碟吞吐率 t、平均訪問耗時 s、資料量 n、每個資料大小 x 都是常量,沒得改。

一共就 ntfsx 五個引數,接下來只有 f 了,這個東西是個變數,取決於查詢過濾條件。比如你想查身高150以上的男生,這個過濾條件就沒啥區分度,可能 f=0.8,大部分都會被選出來,但是如果查190以上的男生,可能 f=0.1,只有一小部分會被選出來。

有區別就有不同的應對措施,我們可以根據 f 選擇查索引還是全表掃瞄。直接算一下什麼時候索引查詢比全表掃瞄快,也就是下邊這個式子:

nfs + nfx/t < nx/t

即:f < x / (ts+x)

可以看到,跟總資料量沒關係,當 f 足夠小的時候,選擇索引比較好。如果結果集比較多,seek過多,那麼全表掃瞄是更優的。

舉個實際例子感受一下:

磁碟吞吐率:t=300 mb/s

單個資料大小:x=128 byte

這個時候,過濾條件的選擇度需要小於 0.008%。

傳統資料庫中一般對索引的介紹是,當表很大的時候可以考慮建立索引。seek是乙個很耗時的操作,需要避免查詢中過多的 seek。同時,資料庫應該根據不同的查詢條件選擇查詢方式。

資料庫漫遊指南

全表掃瞄與索引掃瞄

一,全表掃瞄 全表掃瞄是從讀取資料的同時通過where條件中的查詢條件來過濾來篩選出滿足條件的資料執行過程。其掃瞄的的物件是表中的所有資料塊,包括空資料庫,如果表中的資料大量被刪除,那麼就會存在大量的空資料塊,再次狀態下,大量的空資料塊也被掃瞄。在執行全表掃瞄時,按照順序每次將多個資料塊從磁碟讀取到...

全表掃瞄和索引掃瞄的區別

1 全表掃瞄 full table scans,fts 為實現全表掃瞄,oracle讀取表中所有的行,並檢查每一行是否滿足語句的where限制條件。oracle順序地讀取分配給表的每個資料塊,直到讀到表的最高水線處 high water mark,hwm,標識表的最後乙個資料塊 乙個多塊讀操作可以使...

陷阱 SQL全表掃瞄與聚集索引掃瞄

sqlserver中在查詢時,我們為了優化效能,通常會為where條件的字段建立索引,如果條件比較固定還會建立組合索引,接下來,我們來看一下索引與查詢的相關知識及相關陷阱。表自動為主鍵加聚集索引的猜想 我認為應該是對查詢的優化,因為如果聚集 最多只能有乙個 索引的話,在 查詢時,將進行全表掃瞄,反之...