MySQL理解索引、添加索引的原則

索引用於快速找出在某個列中有一特定值的行。不使用索引,MySQL必須從第1條記錄開始而後讀完整個表直到找出相關的行,還須要考慮每次讀入數據頁的IO開銷。而若是採起索引,則能夠根據索引指向的頁以及記錄在頁中的位置,迅速地讀取目標頁進而獲取目標記錄。mysql

大多數狀況下都(默認)採用B樹來構建索引。只是空間列類型的索引使用R-樹,而且MEMORY表還支持hash索引。B樹是平衡多叉樹,每一個節點存放多少個值取決於值所佔的空間,這與每一張數據頁存放多少條記錄與記錄信息量有關同理。節點中的值是以非降序進行排列的,節點中的值老是小於等於指向它的結點中的值。sql

MySQL使用B樹構造索引的狀況下,是由葉子指向具體的頁和記錄的。而且一個葉子有一個指針指向下一個葉子。函數

 

使用索引須要注意:優化

⑴只對WHERE和ORDER BY須要查詢的字段設置索引,避免無心義的硬盤開銷;google

⑵組合索引支持前綴索引;spa

⑶更新表的時候,如增刪記錄,MySQL會自動更新索引,保持樹的平衡;所以更多的索引意味着更多的維護成本設計

 索引的字段類型問題指針

  • text類型,也可建索引(需指定長度)
  • myisam存儲引擎索引鍵長度綜合不能超過1000字節
  • 用來篩選的值儘可能保持和索引列一樣的數據類型

索引分四類:htm

index ----普通的索引,數據能夠重複排序

fulltext----全文索引,用來對大表的文本域(char,varchar,text)進行索引。語法和普通索引同樣。 

unique ----惟一索引,惟一索引,要求全部記錄都惟一

primary key ----主鍵索引,也就是在惟一索引的基礎上相應的列必須爲主鍵

like 不能用索引?

  • 儘可能減小like,但不是絕對不可用,」xxxx%」 是能夠用到索引的,

想象一下,你在看一本成語詞典,目錄是按成語拼音順序創建,查詢需求是,你想找以 「一」字開頭的成語(」一%「),和你想找包含一字的成語(「%一%」)

  • 除了like,如下操做符也可用到索引:

<,<=,=,>,>=,BETWEEN,IN

<>,not in ,!=則不行

 

原則

   1,單表數據太少,索引反而會影響速度;更新很是頻繁的數據不適宜建索引

   2,where後的條件,order by ,group by 等這樣過濾時,後面的字段最好加上索引。根據實際狀況,選擇PRIMARY KEY、UNIQUE、INDEX等索引,可是不是越多越好,要適度

    3,聯合查詢,子查詢等多表操做時關連字段要加索引

ps:數據量特別大的時候,最好不要用聯合查詢,即便你作了索引

多列查詢該如何建索引?

一次查詢只能用到一個索引,因此 首先槍斃 a,b各建索引方案

a仍是b? 誰的區分度更高(同值的最少),建誰!

固然,聯合索引也是個不錯的方案,ab,仍是ba,則同上,區分度高者,在前

聯合索引的問題?

where a = 「xxx」 可使用 AB 聯合索引
where b = 「xxx」 則不可 (再想象一下,這是書的目錄?)

因此,大多數狀況下,有AB索引了,就能夠不用在去建一個A索引了

詳解:

聯合索引又叫複合索引。對於複合索引:Mysql從左到右的使用索引中的字段,一個查詢能夠只使用索引中的一部份,但只能是最左側部分。例如索引是key index (a,b,c). 能夠支持a | a,b| a,b,c 3種組合進行查找,但不支持 b,c進行查找 .當最左側字段是常量引用時,索引就十分有效。


兩個或更多個列上的索引被稱做複合索引。
利用索引中的附加列,您能夠縮小搜索的範圍,但使用一個具備兩列的索引 不一樣於使用兩個單獨的索引。複合索引的結構與電話簿相似,人名由姓和名構成,電話簿首先按姓氏對進行排序,而後按名字對有相同姓氏的人進行排序。若是您知 道姓,電話簿將很是有用;若是您知道姓和名,電話簿則更爲有用,但若是您只知道名不姓,電話簿將沒有用處。
因此說建立複合索引時,應該仔細考慮列的順序。對索引中的全部列執行搜索或僅對前幾列執行搜索時,複合索引很是有用;僅對後面的任意列執行搜索時,複合索引則沒有用處。
如:創建 姓名、年齡、性別的複合索引。

create table test(
a int,
b int,
c int,
KEY a(a,b,c)
);

優: select * from test where a=10 and b>50
差: select * from test where a50

優: select * from test order by a
差: select * from test order by b
差: select * from test order by c

優: select * from test where a=10 order by a
優: select * from test where a=10 order by b
差: select * from test where a=10 order by c

優: select * from test where a>10 order by a
差: select * from test where a>10 order by b
差: select * from test where a>10 order by c

優: select * from test where a=10 and b=10 order by a
優: select * from test where a=10 and b=10 order by b
優: select * from test where a=10 and b=10 order by c

優: select * from test where a=10 and b=10 order by a
優: select * from test where a=10 and b>10 order by b
差: select * from test where a=10 and b>10 order by c



mysql 複合索引,聯合索引 - flyflying1987 - ly
索引原則

1.索引越少越好
緣由:主要在修改數據時,第個索引都要進行更新,下降寫速度。
2.最窄的字段放在鍵的左邊
3.避免file sort排序,臨時表和表掃描.

哪些常見狀況不能用索引?

  • like 「%xxx」
  • not in , !=
  • 對列進行函數運算的狀況(如 where md5(password) = 「xxxx」)
  • WHERE index=1 OR A=10
  • 存了數值的字符串類型字段(如手機號),查詢時記得不要丟掉值的引號,不然沒法用到該字段相關索引,反之則不要緊

也即

select * from test where mobile = 13711112222;

但是沒法用到mobile字段的索引的哦(若是mobile是char 或 varchar類型的話)

btw,千萬不要嘗試用int來存手機號(爲何?本身想!要不本身試試)

 

覆蓋索引(Covering Indexes)擁有更高效率

索引包含了所需的所有值的話,就只select 他們,換言之,只select 須要用到的字段,如無必要,可儘可能避免select *

NULL 的問題

NULL會致使索引形同虛設,因此在設計表結構時應避免NULL 的存在(用其餘方式表達你想表達的NULL,好比 -1?)

如何查看索引信息,如何分析是否正確用到索引?

show index from tablename;
explain select ……;

關於explain,改天能夠找個時間專門寫一篇入門帖,在此以前,能夠嘗試 google

瞭解本身的系統,不要過早優化!

過早優化,一直是個很是討厭而又時刻存在的問題,大多數時候就是由於不瞭解本身的系統,不知道本身系統真正的承載能力

好比:幾千條數據的新聞表,天天幾百幾千次的正文搜索,大多數時候咱們能夠放心的去like,而不要又去建一套全文搜索什麼的,畢竟cpu仍是比人腦厲害太多

最後:永遠別忘記的關鍵詞 sql注入

相關文章
相關標籤/搜索