20分鐘數據庫索引設計實戰

在後端開發的工做中如何輕鬆、高效地設計大量數據庫索引呢?經過下面這四步,20分鐘後你就不再會爲數據庫的索引設計而發愁了。數據庫

順暢地閱讀這篇文章須要瞭解數據庫索引的組織方式,若是你還不熟悉的話,能夠經過另外一篇文章來快速瞭解一下——數據庫索引融會貫通segmentfault

這篇文章是一系列數據庫索引文章中的第三篇,這個系列包括了下面四篇文章:後端

  1. 數據庫索引是什麼?新華字典來幫你 —— 理解
  2. 數據庫索引融會貫通 —— 深刻
  3. 20分鐘數據庫索引設計實戰 —— 實戰
  4. 數據庫索引爲何用B+樹實現? —— 擴展

這一系列涵蓋了數據庫索引從理論到實踐的一系列知識,一站式解決了從理解到融會貫通的全過程,相信每一篇文章均可以給你帶來更深刻的體驗。優化

1. 整理查詢條件

咱們設計索引的目的主要是爲了加快查詢,因此,設計索引的第一步是整理須要用到的查詢條件,也就是咱們會在where子句、join鏈接條件中使用的字段。通常來講會整理程序中除了insert語句以外的全部SQL語句,按不一樣的表分別整理出每張表上的查詢條件。也能夠根據對業務的理解添加一些暫時尚未使用到的查詢條件。網站

對索引的設計通常會逐表進行,因此按數據表收集查詢條件能夠方便後面步驟的執行。設計

2. 分析字段的可選擇性

整理出全部查詢條件以後,咱們須要分析出每一個字段的可選擇性,那麼什麼是可選擇性呢?code

字段的可選擇性指的就是字段的值的區分度,例如一張表中保存了用戶的手機號、性別、姓名、年齡這幾個字段,且一個手機號只能註冊一個用戶。在這種狀況下,像手機號這種惟一的字段就是可選擇性最高的一種狀況;而年齡雖然有幾十種可能,可是區分度就沒有手機號那麼大了;性別這樣的字段則只有幾種可能,因此可選擇性最差。因此俺可選擇性從高到低排列就是:手機號 > 年齡 > 性別。索引

可是不一樣字段的值分佈是不一樣的,有一些值的數量是大體均勻的,例如性別爲男和女的值數量可能就差異不大,可是像年齡超過100歲這樣的記錄就很是少了。因此對於年齡這個字段,20-30這樣的值就是可選擇性很小的,由於每個年齡都有很是多的記錄;可是像100這樣的值,那它的可選擇性就很是高了。後端開發

若是咱們在表中添加了一個字段表示用戶是不是管理員,那麼在查詢網站的管理員信息列表時,這個字段的可選擇性就很是高。可是若是咱們要查詢的是非管理員信息列表時,這個字段的可選擇性就很是低了。開發

從經驗上來講,咱們會把可選擇性高的字段放到前面,可選擇性低的字段放在後面,若是可選擇性很是低,通常不會把這樣的字段放到索引裏。

3. 合併查詢條件

雖然索引能夠加快查詢的效率,可是索引越多就會致使插入和更新數據的成本變高,由於索引是分開存儲的,全部數據的插入和更新操做都要對相關的索引進行修改。因此設計索引時還須要控制索引的數量,不能盲目地增長索引。

通常咱們會根據最左匹配原則來合併查詢條件,儘量讓不一樣的查詢條件使用同一個索引。例若有兩個查詢條件where a = 1 and b = 1where b = 1,那麼咱們就能夠建立一個索引idx_eg(b, a)來同時服務兩個查詢條件。

同時,由於範圍條件會終止使用索引中後續的字段,因此對於使用範圍條件查詢的字段咱們也會盡量放在索引的後面。

4. 考慮是否須要使用全覆蓋索引

最後,咱們會考慮是否須要使用全覆蓋索引,由於全覆蓋索引沒有回表的開銷,效率會更高。因此通常咱們會在回表成本特別高的狀況下考慮是否使用全覆蓋索引,例如根據索引字段篩選後的結果須要返回其餘字段或者使用其餘字段作進一步篩選的狀況。

例如,咱們有一張用戶表,其中有年齡、姓名、手機號三個字段。咱們須要查詢在指定年齡的全部用戶的姓名,已有索引idx_age_name(年齡, 姓名),目前咱們使用下面這樣的查詢語句進行查詢:

SELECT *
FROM 用戶表
WHERE 年齡 = ?;

通常狀況下,將一個索引優化爲全覆蓋索引有兩種方式:

  1. 增長索引中的字段,讓索引字段覆蓋SQL語句中使用的全部字段

    • 在這個例子中,咱們能夠建立一個同時包含全部字段的索引idx_all(年齡, 姓名, 手機號),以此提升查詢的效率。
  2. 減小SQL語句中使用的字段,使SQL須要的字段都包含在現有索引中

    • 在這個例子中,其實更好的方法是將SELECT子句修改成SELECT 姓名,由於咱們的需求只是查詢用戶的姓名,並不須要手機號字段,去掉SELECT子句多餘的字段不只可以知足咱們的需求,並且也不用對索引作修改。
相關文章
相關標籤/搜索