相關(guān)于數(shù)據(jù)庫表索引,一直沒有仔細(xì)閱讀相關(guān)的資料。上周,在網(wǎng)上看到一篇博客,看Sybase官方手冊學(xué)索引工作原理,其總結(jié)的是SAP ASEv12,讀后收獲不小,特地也找了下SAP ASEv16.0的Performance and Tuning Series- Locking and Concurrency Control文檔,試著翻譯了一部分,以備學(xué)習(xí)。
7 索引
索引是用于提升數(shù)據(jù)庫性能的重要設(shè)計(jì)要素,它可以明顯地加速數(shù)據(jù)檢索過程(增刪改查):
- 避免表掃描。
- 不訪問數(shù)據(jù)行,而從非聚集索引中獲取數(shù)據(jù)。
- 聚集索引有助于隨機(jī)插入數(shù)據(jù)從而避免在表的最后頁插入。
- 如果索引的順序匹配了order by子句的列順序,索引有助于避免排序。
- 對于大多數(shù)分區(qū)域的表,用戶可以使用一個(gè)覆蓋全表的帶有索引樹的全局索引,或者創(chuàng)建多個(gè)帶有索引樹的本地索引,其中每一個(gè)索引覆蓋表的一個(gè)分區(qū)。
雖然索引加速了數(shù)據(jù)檢索,但是它們也可能減慢數(shù)據(jù)的修改,因?yàn)閷τ诖蠖鄶?shù)據(jù)修改需索引更新。優(yōu)化索引有必要理解如下內(nèi)容:
- 對于不同索引表類型的查詢行為。例如,無索引的堆表,帶有聚集索引的表及帶有非聚集索引的表。
- 混合查詢。
- 在分區(qū)表上的本地和全局索引的彼此相對優(yōu)勢。
- SAP ASE的優(yōu)化器。
7.1 索引類型
SAP ASE 提供的兩種通用索引類型:
- 聚集索引,數(shù)據(jù)在物理上依照索引鍵的順序存儲:
- 對于全頁鎖類型(allpages-locked,事務(wù)處理時(shí),既鎖數(shù)據(jù)頁,又鎖索引頁,且只有表鎖和頁鎖。)的表,在頁上的行依照索引鍵的順序保存,并且頁也依照索引鍵的順序鏈接。
- 對于數(shù)據(jù)鎖類型(data-only-locked,事務(wù)處理時(shí),只鎖數(shù)據(jù)頁,不鎖索引頁,具有表鎖、頁鎖和行鎖)的表,索引被用于指引存儲在行和頁上的數(shù)據(jù),但嚴(yán)格的鍵順序不被維護(hù)。
- 非聚集索引,表上的數(shù)據(jù)存儲順序與索引的鍵無關(guān)。
用戶只能在一個(gè)表或分區(qū)上創(chuàng)建一個(gè)聚集索引,因?yàn)橹豢赡苡幸环N數(shù)據(jù)行的順序。用戶在每個(gè)表上可以創(chuàng)建249個(gè)費(fèi)聚集索引。
沒有聚集索引的表也叫做堆。這樣的表中的行沒有指定順序,所有新增加的行都被增加到表的最后。
基于函數(shù)的索引是一種非聚集索引,它使用一個(gè)或多個(gè)表達(dá)式作為索引的鍵。
7.1.1 索引頁
索引實(shí)體在索引頁上作為行保存,其格式近似于在數(shù)據(jù)頁上數(shù)據(jù)行。索引實(shí)體保存健值和指針,這些指針指向的是更下一級的索引、數(shù)據(jù)頁、或者單獨(dú)的數(shù)據(jù)行。
SAP ASE 使用B-tree索引,在其索引結(jié)構(gòu)中每一節(jié)點(diǎn)都可以有多個(gè)子節(jié)點(diǎn)。
索引實(shí)體通常比數(shù)據(jù)頁中的數(shù)據(jù)行更小,并且索引頁也顯然比數(shù)據(jù)頁排布地更緊密。假設(shè)數(shù)據(jù)行有 200 bytes(包括行的基本開銷),在頁大小為2K的服務(wù)器上,每一頁就有10行。然而同樣頁大小(2K)的條件下,一個(gè)基于15-byte行域大小的索引在每個(gè)索引頁上有會有100行(每個(gè)行指針需要 4-9 bytes,依賴于其索引類型和索引等級)。
索引可以有多個(gè)等級:
- 根等級(Root level)
- 葉等級(Leaf level)
- 中間等級(Intermediate level)
7.1.1.1 根等級
根等級是索引最高等級。只有唯一一個(gè)根索引頁。
如果全頁鎖類型(allpages-locked)的表非常小,則整個(gè)索引容納于單索引頁,沒有中間等級索引及葉等級索引,根索引頁保存了指向數(shù)據(jù)頁的指針。
數(shù)據(jù)鎖類型(data-only-locked)的表在根索引頁和數(shù)據(jù)頁之間一直有葉等級索引。
對于比較大的表,根等級索引頁保存的指針,指向中間等級索引頁或是葉等級索引頁。
7.1.1.2 葉等級
索引最低等級是葉等級
在葉等級,對應(yīng)一個(gè)數(shù)據(jù)表中每一行的健值包含一個(gè)索引中,并且這些行依照索引鍵的順序保存:
- 對于在全頁瑣類型的表上的聚集索引,葉等級索引就是數(shù)據(jù)。沒有其他等級的索引包含對應(yīng)每一數(shù)據(jù)行的某一索引行。
- 對于在數(shù)據(jù)鎖類型表上的非聚集索引和聚集索引,葉等級索引包含的的健值,對應(yīng)每一行,每一個(gè)指向頁的指針,以及包含有特定健值的行。
葉等級僅僅是在數(shù)據(jù)上的等級;它對于每一數(shù)據(jù)行都有一個(gè)索引行。在索引頁上的索引行都以鍵值順序保存。
7.1.1.3 中間等級
所有在根等級和葉子等級間的等級都是中間等級。在大表上索引或是使用了長鍵的索引都有很多中間等級索引。在非常小的表上很可能沒有中間等級索引,即根索引頁直接指向了葉索引等級。
7.1.2 索引大小
針對于APL(allpages-locked)和DOL(data-only-locked)表的索引大小限制:
| 頁大小 | 用戶可見的索引行大小限制 | 內(nèi)部額索引行大小限制 |
|---|---|---|
| 2K(2048 bytes) | 600 | 650 |
| 4K(4096 bytes) | 1250 | 1310 |
| 8K(8192 bytes) | 2600 | 2670 |
| 16K(16384 bytes) | 5300 | 5400 |
用戶可以創(chuàng)建表,其列的寬度比其索引的鍵的限制寬,然而這些列卻是不可索引的。例如,用戶執(zhí)行如下語句在2K大小頁的數(shù)據(jù)庫服務(wù)器上,那么創(chuàng)建一個(gè)在c3上的索引,執(zhí)行命令會失敗,并且SAP ASE報(bào)出一個(gè)錯(cuò)誤信息,即由c3超出索引行的大小限制(600 bytes):
create table t1 (c1 intc2 intc3 char(700))
用戶可以為不可索引的列創(chuàng)建統(tǒng)計(jì)數(shù)據(jù),或者包含在搜索結(jié)果中。并且如果用戶把這樣的列包含在了where語句中,那么它會在優(yōu)化階段被評估。
一個(gè)索引行的大小過大會導(dǎo)致頻繁地使索引頁分拆。索引頁分拆可以使得索引等級隨著表中數(shù)據(jù)行數(shù)的增加而線性增長,如此的話,由于索引遍歷費(fèi)時(shí)費(fèi)力致使索引失去有效性。SAP ASE限制索引的大小,最多到數(shù)據(jù)庫服務(wù)器設(shè)定的頁大小的1/3,這樣每一索引頁都包含至少三個(gè)索引行。
未完待續(xù)……