MySQL資料庫索引
目錄
索引是什麼
索引是對資料庫表中一個或多個列的值進行排序的結構,是幫助MySQL高效獲取資料的資料結構
你也可以這樣理解:索引就是加快檢索表中資料的方法。資料庫的索引類似於書籍的索引。在書籍中,索引允許使用者不必翻閱完整本書就能迅速地找到所需要的資訊。在資料庫中,索引也允許資料庫程式迅速地找到表中的資料,而不必掃描整個資料庫。
MySQL資料庫幾個基本的索引型別:普通索引、唯一索引、主鍵索引、全文索引
1.索引加快資料庫的檢索速度
2.索引降低了插入、刪除、修改等維護任務的速度
3.唯一索引可以確保每一行資料的唯一性
4.通過使用索引,可以在查詢的過程中使用優化隱藏器,提高系統的效能
5.索引需要佔物理和資料空間
資料庫有哪些索引
在MySql資料庫中,有四種索引:聚集索引(主鍵索引)(聚簇索引)、普通索引、唯一索引以及全文索引(FUNLLTEXT INDEX)
索引又可分為聚簇索引和非聚簇索引兩種
唯一索引
一種索引,不允許具有索引值相同的行,從而禁止重複的索引或鍵值。系統在建立該索引時檢查是否有重複的鍵值,並在每次使用 INSERT 或 UPDATE 語句新增資料時進行檢查。
CREATE UNIQUE CLUSTERED INDEX myclumn_cindex ON mytable(mycolumn)
聚簇索引與非聚簇索引
可以理解為主鍵索引與普通索引
聚簇索引:是對磁碟上實際資料重新組織以按指定的一個或多個列的值排序的演算法。特點是儲存資料的順序和索引順序一致,且一個表只能有一個聚簇索引,因為物理儲存只能有一個順序。主鍵索引一般都是聚簇索引 非聚簇索引:表資料儲存順序與索引順序無關。對於非聚簇索引,葉結點包含索引欄位值及指向資料頁資料行的邏輯指標,其行數量與資料錶行資料量一致。非聚簇索引記錄的物理順序與邏輯順序沒有必然的聯絡,與資料的儲存物理結構沒有關係;一個表對應的非聚簇索引可以有多條,根據不同列的約束可以建立不同要求的非聚簇索引; 一般情況下主鍵會預設建立聚簇索引,且一張表只允許存在一個聚簇索引。因為物理儲存只能有一個順序。 聚簇索引的葉子節點就是資料節點(Innodb的B+樹的主鍵對應的資料節點),而非聚簇索引的葉子節點仍然是索引節點,只不過有指向對應資料塊的指標。 聚簇索引主鍵的插入速度要比非聚簇索引主鍵的插入速度慢很多。 相比之下,聚簇索引適合排序,非聚簇索引不適合用在排序的場合。因為聚簇索引本身已經是按照物理順序放置的,排序很快。非聚簇索引則沒有按序存放,需要額外消耗資源來排序。 建立聚簇索引的語句: CREATE CLUSTER INDEX index_name ON table_name(column_name1,...); |
全文索引
全文索引(也稱全文檢索)是目前搜尋引擎使用的一種關鍵技術。它能夠利用【分詞技術】等多種演算法智慧分析出文字文字中關鍵詞的頻率和重要性,然後按照一定的演算法規則智慧地篩選出我們想要的搜尋結果。 select * from 表名 where 標題 like '%xxx%' or 內容 like '%xxx%' or 作者 like '%xxx%'; 這種搜尋效率無比底下 全文索引是為了使得“關鍵詞搜尋”功能更加的高效能。 我們有這麼一張資料表: 文章id 文章標題 文章內容 1 超級塞亞人 我是超級塞亞人我喜歡吃蘋果,我不是天朝的人,也不是地球人 2 天朝大國 我大天朝威武,我大天朝13億人,我大天朝 3 我喜歡游泳 游泳有很多好方法 4 動畫片 我兒子喜歡看動畫片,尤其是七龍珠,因為裡面有塞亞人,而且塞亞人喜歡吃蘋果,他們不是地球人 5 運動 我喜歡運動,喜歡跑步,喜歡游泳,喜歡健身,喜歡xxoo 6 打炮 我是一個二戰的老兵,這是我的回憶錄,我最幸福的時光就是在天朝吃著蘋果打炮 7 。。。 8 。。。 9 。。。 然後,根據以上的文章內容,如果建立了一個索引檔案(這裡忽略索引檔案的資料結構,僅僅以一種易於理解的方式呈現): 關鍵詞 文章id 塞亞人 1,4 蘋果 1,4,6 天朝 1,2,6 地球 1,4 游泳 3,5 七龍珠 4 喜歡 1,4,5,6 那麼當我想搜尋 “塞亞人”的時候,這個索引檔案直接告訴我在文章id為1和4的文章裡有這個詞。 這個索引檔案就是“全文索引”。 如何使用全文索引和分詞的方式來幫助優化你的搜尋呢? 需要工作的程式:索引程式,分詞程式,資料庫。 工作原理: 1、索引程式從資料庫讀取資料,比如上面例子中的資料表,索引程式通過sql語句:select 文章id,文章標題,文章內容 from 文章表.獲得文章的相關資料 2、索引程式對需要索引的內容進行“分詞”,而這裡的分詞就是呼叫分詞程式啦! 3、索引程式對分好詞的一個個詞條加入索引檔案。 在你寫的程式碼裡,原來到資料庫----like %xxx%-----的語句就變成了到索引檔案裡去查詢,從而找到相應的資料(這點相信你已經理解啦!) 建立全文索引的兩種方法: 1.在建表語句中 2.在已知表中 ALTER TABLE article ADD FULLTEXT INDEX fulltext_article(title,content); 具體如何使用全文索引呢? 不用全文索引時的寫法:SELECT * FROM article WHERE content LIKE ‘%查詢字串%’; 使用全文索引:SELECT * FROM article WHERE MATCH(title,content) AGAINST (‘查詢字串’); 注意: 1、MySql自帶的全文索引只能對英文進行全文檢索,目前無法對中文進行全文檢索。如果需要對包含中文在內的文字資料進行全文檢索,我們需要採用Sphinx(斯芬克斯)/Coreseek技術來處理中文。 2、使用MySql自帶的全文索引時,如果查詢字串的長度過短將無法得到期望的搜尋結果。MySql全文索引所能找到的詞預設最小長度為4個字元。另外,如果查詢的字串包含停止詞,那麼該停止詞將會被忽略。 3、如果可能,請儘量先建立表並插入所有資料後再建立全文索引,而不要在建立表時就直接建立全文索引,因為前者比後者的全文索引效率要高。 |
使用索引一定能提高查詢效能嗎?
通常,通過索引查詢資料比全表掃描要快,但是我們也必須注意到它的代價.
索引需要空間來儲存,也需要定期維護, 每當有記錄在表中增減或索引列被修改時,索引本身也會被修改。這意味著每條記錄的INSERT,DELETE,UPDATE將為此多付出4,5次的磁碟I/O.
索引不但會使得插入和修改的效率降低,而且在查詢的時候,有一個查詢優化器,太多的索引會讓優化器困惑,可能沒有辦法找到正確的查詢路徑,從而選擇了慢的索引。
索引範圍查詢(INDEX RANGE SCAN)適用於兩種情況:
1.基於一個範圍的檢索,一般查詢返回結果集小於表中記錄數的30%
2.基於非唯一性索引的檢索
3.直接晉升為覆蓋索引,避免多次查表
哪些情況下設定了索引但是無法使用
- 對單欄位建了索引,where條件多欄位。
- 建立組合索引,where條件單欄位。與上面情況正好相反。INDEX(a,b,c),當條件為a或a,b或a,b,c或a,c時都可以使用索引,但是當條件為b,c時將不會使用索引。也就是說不是使用的第一部分,則不會使用索引。如果是INDEX(a,b),即使查詢的where是b,a,由於sql優化器的優化作用,會把b,a換成a,b,這樣就可以走索引了。如果是index(a,b,c),查詢是(a,b,c,d)不會走索引
- 條件中用or,即使其中有條件帶索引,也不會使用索引查詢(這就是查詢儘量不要用or的原因,用in)(注意:使用or,又想索引生效,只能將or條件中的每個列都加上索引,這樣查詢時每個列都會單獨使用它們自己的索引)
- like的模糊查詢的模糊詞在字串前面,比如以%或_開頭,索引失效。
- 在使用不等於(is null、is not null、!= 、<>)的時候無法使用索引會導致全表掃描。
- 型別錯誤,如欄位型別為varchar,where條件用number。
- 對索引應用內部函式,這種情況下應該建立基於函式的索引。
- 索引列不能是表示式(id+1=5)的一部分,也不能是函式的引數
- 如果MySQL預計使用全表掃描要比使用索引快,則不使用索引
哪些情況下需要設定索引、哪些情況下不需要
需要: 1).主鍵自動建立唯一索引 2).頻繁作為查詢條件的欄位應該建立索引 3).查詢中與其它表關聯的欄位,外來鍵關係建立索引 4).單鍵/組合索引的選擇問題(在高併發下傾向建立組合索引) 5).查詢中排序的欄位,排序欄位若通過索引去訪問將大大提高排序速度 6).查詢中統計或者分組欄位 不需要: 1).表記錄太少 2).經常增刪改的表(因為不僅要儲存資料,還要儲存一下索引檔案) 索引本來是一種事先在寫的階段形成一定的資料結構,從而使得在讀的階段效率較高的方式,但是如果一個欄位是寫多讀少,則會降低寫的速度。 3).資料重複且分佈平均的表字段(比如性別),因此應該只為最經常查詢和最經常排序的資料列建立索引。 4).where條件裡用不到的欄位不建立索引 |
什麼情況下應該使用組合索引而非單獨索引
假設有條件語句A=a AND B=b,如果A和B是兩個單獨的索引,在AND條件下只有一個索引起作用,對於B則要逐個判斷,而如果使用組合索引(A, B),只要遍歷一棵樹就可以了,大大增加了效率。但是對於A=a OR B=b,由於是或的關係,因而組合索引是不起作用的,因而可以使用單獨索引,這個時候,兩個索引可以同時起作用。 |