上星期寫了一個篇文章,數據庫方面的面試技巧,如何從建表方面展現本身能力,承蒙管理員擡舉,放入首頁,也承蒙各位厚愛,兩天內收穫了將近770個點擊,也一度進入48小時熱榜。html
爲了感謝管理員和你們的支持,再根據個人面試經驗原創一篇關於索引方面如何推銷本身的文章。這內容也來自我寫的書java
若是咱們須要招個Java方面的高級程序員,一方面看年限(本科3年),具體到數據庫方面的技能要求,包括以下三個方面:web
第一,是否會基本的增刪改查,存儲過程等技能,是否會用些group by, having,distinct, exist, in, with等高級點的語句。這點通常都沒問題,甚至一個剛畢業的大學生或工做經驗2年以內的初級程序員也沒問題,也就是說,這個是高級程序員必備的,你會了是應該,不會甚至不及畢業生。面試
第二,有沒有設計表的經驗,這方面的面試技能也已經在數據庫方面的面試技巧,如何從建表方面展現本身能力裏說了,關鍵一點,你得結合實際需求來講。數據庫
第三也是關鍵一點,在數據庫優化方面,你是否有相關經驗。函數
這是個開放性的問題,大神們知道,能夠從分區,根據執行計劃優化等不少方面來考慮,對高級程序員,個人指望是你至少能說點索引相關的。但根據個人面試經驗,不多有候選人(特別是高級程序員候選人)能比較深刻地敘述。工具
開場白說了很多,下面進入正文。性能
索引是數據庫優化所必需的工具,在面試的時候通常不會問概念性的問題,由於你們都能從教科書上找到答案,因此通常會問如下兩方面的問題:優化
①索引有什麼代價?哪些場景下你須要建索引?或者有時候反過來問,哪些場景下不推薦建索引。
②建好索引以後,怎麼才能最高效地利用索引?或者反過來問,請說出一個沒法有效利用已建索引的案例。
從結構上來看,索引比如是一棵B樹(也叫B*或者B+),假設學生表裏只有學生ID和姓名兩列,該學生表裏有1000個學生,學號分別從1到1000,若是針對ID創建索引,大體的結構以下圖所示。
固然,在實際的數據庫系統中,索引要比這個複雜得多,但從這個圖裏,咱們能大體看出索引的工做原理。
索引建好後,若是咱們要查找ID爲111的學生,則數據庫系統就會走索引,從圖2.1中咱們能夠看到,根據根節點的指引,會 找到第二層從左往右第二個數據塊,以此類推,會在第四層裏獲得ID爲111的物理地址,而後直接從硬盤裏找數據。
反過來,若是沒有建索引,數據庫系統可能就要從一個大的範圍裏逐必定位查找,效率就沒這麼高了。
索引的好處你們已經看到了,那麼爲了獲得這個「查詢效率高」的好處,咱們要付出了什麼樣的代價呢?
1 索引須要佔硬盤空間,這是空間方面的代價。
2 一旦插入新的數據,就須要從新建索引,這是時間上的代價。
關於索引性能問題,我會細問,你建索引的表規模多少?很多人直接告訴我表就幾千條,我或者問,索引有什麼代價?很多回答是索引是隻有好處沒壞處的, 也就是說,能夠隨便建。
對此咱們來詳細分析下(也就是你們在面試時須要說的):
場景一,數據表規模不大,就幾千行,即便不建索引,查詢語句的返回時間也不長,這時建索引的意義就不大。固然,若就幾千行,索引所佔的空間也很少,因此這種狀況下,頂多屬於「性價比」不高。
場景二,某個商品表裏有幾百萬條商品信息,同時天天會在一個時間點,往其中更新大概十萬條左右的商品信息,如今用where語句查詢特定商品時(好比where name = ‘XXX’)速度很慢。爲了提高查詢效率能夠建索引,但當天天更新數據時,又會重建索引,這是要耗費時間的。這時就須要綜合考慮,甚至能夠在更新前刪除索引,更新後再重建。
場景三,從上圖中能夠看到,由於在數據表裏ID值都不相同,因此索引能發揮出比較大的做用。相反,若是某個字段重複率很高,如性別字段,或者某個字段大多數值是空(null),那麼不建議對該字段建索引。
請你們記住,必定是有業務需求了纔會建索引。好比在一個商品表裏,咱們常常要根據name作查詢,若是沒有索引,查詢速度會很慢,這時就須要建索引。但在項目開發中,若是不常常根據商品編號查詢,那麼就不必對編號建索引。
最後再強調一次,建索引是要付出代價的,沒事別亂建着玩,同時在一個表上也不能建太多的索引。
下面說下索引建好了該怎麼用?畢竟你們花了很多時間和空間代價建了索引,至少得回本吧?
若是出現一些很差的SQL語句,那麼索引就白建了。下面經過一些具體的例子來看索引的正確用法。
①語句一:select name from 商品表。不會用到索引,由於沒有where語句。
②語句二:select * from 商品表 where name = ‘Java書’,會用到索引,若是項目裏常常用到name來查詢,且商品表的數據量很大,而name值的重複率又不高,那麼建議建索引。
③語句三:select * from 商品表 where name like ‘Java%’ 這是個模糊查詢,會用到索引,請你們記住,用like進行模糊查詢時,若是第一個就是模糊的匹配符,好比where name like ‘%java’,那麼在查詢時不會走索引。在其餘狀況下,不論用了多少個%,也不論%的位置,只要不出如今第一個位置,那麼都能用到索引。
學生成績表裏有兩個字段:姓名和成績。如今對成績這個整數類型的字段建索引。
①第一種狀況,當數字型字段遇到非等值操做符時,沒法用到索引。好比:
select name from 學生成績表 where 成績>95 , 一旦出現大於符號,就不能用到索引,爲了用到索引,咱們應該改一下SQL語句裏的where從句:where 成績 in (96,97,98,99,100)
② 第二種狀況,若是對索引字段進行了某種左值操做,那麼沒法用到索引。
能用到索引的寫法:select name from 學生成績表 where 成績 = 60
不能用到索引的寫法:select name from 學生成績表 where 成績+40 = 100
③ 第三種狀況,若是對索引字段進行了函數操做,那麼沒法用到索引。
好比SQL語句:select * from 商品表 where substr(name) = ‘J’,咱們但願查詢商品名首字母是J的記錄,可一旦針對name使用函數,即便name字段上有索引,也沒法用到。
關於索引,固然還有位圖索引和複合索引等,若是你們要應聘更高級的崗位(好比有5年經驗了),那麼就不能止步於此了,但根據個人面試經驗,上述關於索引的說辭對工做經驗3年如下的候選人是有幫助的。
其實我知道,很多程序員平時用過索引,但不知道怎麼說,這很吃虧。對於高級程序員而言,若是你這都說很差,那麼你的能力比初級的要高多少?對於初級程序員而言,若是你掌握了,並且能在面試中很好地說,那麼你和同等能力的人相比,就很佔優點。