在後端開發的工作中如何輕鬆、高效地設計大量資料庫索引呢?通過下面這四步,20分鐘後你就再也不會為資料庫的索引設計而發愁了。
我們設計索引的目的主要是為了加快查詢,所以,設計索引的第一步是整理需要用到的查詢條件,也就是我們會在where子句、join連線條件中使用的字段。一般來說會整理程式中除了insert語句之外的所有sql語句,按不同的表分別整理出每張表上的查詢條件。也可以根據對業務的理解新增一些暫時還沒有使用到的查詢條件。
對索引的設計一般會逐表進行,所以按資料表收集查詢條件可以方便後面步驟的執行。
整理出所有查詢條件之後,我們需要分析出每個欄位的可選擇性,那麼什麼是可選擇性呢?
欄位的可選擇性指的就是欄位的值的區分度,例如一張表中儲存了使用者的手機號、性別、姓名、年齡這幾個字段,且乙個手機號只能註冊乙個使用者。在這種情況下,像手機號這種唯一的字段就是可選擇性最高的一種情況;而年齡雖然有幾十種可能,但是區分度就沒有手機號那麼大了;性別這樣的字段則只有幾種可能,所以可選擇性最差。所以俺可選擇性從高到低排列就是:手機號 > 年齡 > 性別。
但是不同欄位的值分布是不同的,有一些值的數量是大致均勻的,例如性別為男和女的值數量可能就差別不大,但是像年齡超過100歲這樣的記錄就非常少了。所以對於年齡這個字段,20-30這樣的值就是可選擇性很小的,因為每乙個年齡都有非常多的記錄;但是像100這樣的值,那它的可選擇性就非常高了。
如果我們在表中新增了乙個字段表示使用者是否是管理員,那麼在查詢**的管理員資訊列表時,這個欄位的可選擇性就非常高。但是如果我們要查詢的是非管理員資訊列表時,這個欄位的可選擇性就非常低了。
從經驗上來說,我們會把可選擇性高的字段放到前面,可選擇性低的字段放在後面,如果可選擇性非常低,一般不會把這樣的字段放到索引裡。
雖然索引可以加快查詢的效率,但是索引越多就會導致插入和更新資料的成本變高,因為索引是分開儲存的,所有資料的插入和更新操作都要對相關的索引進行修改。所以設計索引時還需要控制索引的數量,不能盲目地增加索引。
一般我們會根據最左匹配原則來合併查詢條件,盡可能讓不同的查詢條件使用同乙個索引。例如有兩個查詢條件where a = 1 and b = 1和where b = 1,那麼我們就可以建立乙個索引idx_eg(b, a)來同時服務兩個查詢條件。
同時,因為範圍條件會終止使用索引中後續的字段,所以對於使用範圍條件查詢的字段我們也會盡可能放在索引的後面。
最後,我們會考慮是否需要使用全覆蓋索引,因為全覆蓋索引沒有回表的開銷,效率會更高。所以一般我們會在回表成本特別高的情況下考慮是否使用全覆蓋索引,例如根據索引字段篩選後的結果需要返回其他字段或者使用其他欄位做進一步篩選的情況。
例如,我們有一張使用者表,其中有年齡、姓名、手機號三個字段。我們需要查詢在指定年齡的所有使用者的姓名,已有索引idx_age_name(年齡, 姓名),目前我們使用下面這樣的查詢語句進行查詢:
select *
from 使用者表
where 年齡 = ?;
一般情況下,將乙個索引優化為全覆蓋索引有兩種方式:
增加索引中的字段,讓索引字段覆蓋sql語句中使用的所有字段
在這個例子中,我們可以建立乙個同時包含所有欄位的索引idx_all(年齡, 姓名, 手機號),以此提高查詢的效率。
減少sql語句中使用的字段,使sql需要的字段都包含在現有索引中
在這個例子中,其實更好的方法是將select子句修改為select 姓名,因為我們的需求只是查詢使用者的姓名,並不需要手機號字段,去掉select子句多餘的字段不僅能夠滿足我們的需求,而且也不用對索引做修改。
5分鐘快速部署Docker實戰
1.安裝docker.2.安裝tomcat.3.安裝nginx.名詞解釋 掛載 相當於本地的目錄做個快捷方式到虛擬機器的目錄裡 文章結尾提供以下內容的模板文件.一 安裝docker 1.按提示安裝,下一步下一步.輸入 docker run hello world 有訊息表示安裝成功.1.docker...
MySQL實戰筆記(四)資料庫索引
索引的出現其實就是為了提高資料查詢的效率你,就像書的目錄一樣。一本500頁的書,如果你想找到其中的某個知識點,在沒有目錄的情況下,需要找好久。同樣,對於資料庫的表而言,索引其實就是它的目錄。索引的出現是為了提高查詢效率,但是實現索引的方式和資料結構有多種,先學習其中的三種,它們分別是雜湊表 有序陣列...
五分鐘帶你玩轉rocketMQ(五)實戰廣播與集群
1.集群消費方式 乙個consumergroup中的consumer例項平均分攤消費生產者傳送的訊息。例如某個topic有九條訊息,其中乙個consumer group有三個例項 可能是3個程序,或者3臺機器 那麼每個例項只消費其中的3條訊息,consumer不指定消費方式的話預設是集群消費的,適用...