mysql 索引整理

1:只對 where 和 order by 子句中須要的列添加索引,多餘的索引智慧致使沒必要要的硬盤空間愛你消耗。mysql

每次修改表信息時會更新索引,所以有索引的表性能會相應下降。程序員

2:對於要使用索引的列要使用屬性 NOT NULL , 這樣就永遠不會存儲 null 值。sql

3:最好用惟一化索引,通常狀況下,當查詢優化程序發現某個數據在超過30%的行裏都有出現時,一般會不使用索引而進行全盤掃描。性能

4:索引長度儘可能短。若是要對一個字符型添加索引,好比給 char(50) 字段添加索引,若是它的前10個字節不一樣然後面的基本相同,那麼能夠支隊這前10個字節建立索引mysql索引

這樣能減小索引多佔的空間,又能夠加快檢索速度。測試

5:要充分利用最左側前綴,這是針對複合索引而言的,例如對某表中的 c1 , c2 , c3 三個列建立了一個複合索引,索引項的順序爲 c1 , c2 , c3優化

可在查詢時支隊 c2 , c3 做爲條件,那麼基本上是用不到所建立的複合索引,由於他們都沒有作左側的 c1 字段, 在對一下條件進行檢索時會使用該索引網站

c1 , c2 , c3code

c1 , c2排序

c1

編輯結束; 

 

從接觸PHP以來 一直沒作過真正的大型項目,頂多就作一些 網店啊 ~ 我的博客呀 ~ 中介網啊 這種小型網站。

最近在作一個音樂網,體積不大,可是我手裏的數據量不大不小 ~

前幾天爲了一個查詢 兩表互聯 例如 表 a 和表 b  進行 a right join b 的時候沒什麼異常。

可是因爲查詢結果不是很理想 應當用 a left join b 纔是對的。結果這一個聯表 給我聯了 好幾分鐘都沒有迴應。

分析後發現,2個表相聯的條件是 a 表的主鍵 和 b 表的一個存儲 a 表id列 即 a left join b on a.id = b.aid

而b.aid 沒有索引。 當我給 b.aid 加上索引 在查詢結果發現 恢復了原來的速度。查詢沒有任何異常。

 

對索引 一直是 只是瞭解而並不是真正的體驗過。 由於當我學會索引的時候 我沒有特地的用循環給2個表加10萬條數據進行聯表的測試。

此次的經驗 我知道 原來 索引是這麼的重要。

今天我想完全對mysql索引進行了解。結果在網上搜集了一些資料 一下的我對索引的解說

mysql 索引

普通索引 index

惟一索引 uniqe

全文索引 fulltext

其中 主鍵也是惟一索引。這個應該誰都知道。

首先建立兩個表 分別是 a1 和 a2 每一個表中只有一個字段 id 沒有設置索引 每一個表有5000條記錄

(其實最初我拿10000萬條數據測試 結果等的不耐煩了,改了5000條也等了一小會呢 呵呵)

開始聯表

select * from a1 left join a2 on a1.id = a2.id

耗費時間如圖

 

 

如今給兩個列增長索引 在試一試

alter table a1 add index(id);
alter table a2 add index(id);

結果很明顯,快了多少我就不說了。想象一下,若是你的數據量達到幾萬甚至幾十萬的狀況下

在你是初級程序員的階段 還不瞭解 mysql索引的狀況下 明明sql語句沒有問題 一查就是漫長的進度條 會不會很鬱悶啊。。 呵呵

就算有索引和無索引有如此大的差距 , 但也別有 每一個列 都要加索引的念頭。由於索引壞處被他的好處給掩蓋了。

索引列的信息是保存在 索引文件中,數據表中的數據是保存在數據文件中。

據我瞭解 聯錶帶索引的表時速度快的緣由 是由於 帶有索引的列 在索引文件中會被排序。

例如數字1 - 5000 而沒有索引的列在數據表中是沒有排序的。

 

所以我在聯兩個表時 a1.id left a2.id 的時候 a2中的id 和 a1中的id 互相匹配的過程當中 他們會來回 5000 X 5000 次

因爲沒有索引列沒有排序過,在實際聯表時 由於是 left join 因此 首先 a2.id 要和 a1.id 的 1號相匹配

那麼在第一次匹配的時候 a2.id 的 1號 和 a1.id 的1號匹配了。但此時 匹配並不是中止 a2表中的還會繼續往下找

檢查 1號下面的 id 是否仍是 1 以此類推 他在和 a1.id 中的 1號相聯的時候 他匹配了 5000次

當與 a1.id 的 2號匹配的時候 仍是同樣會去匹配 5000次。

 

而對有索引的列來講 由於索引列的數據排序過,會忽略沒必要要的匹配 所謂排序(據我瞭解) 當我給 a2.id 加索引的那一刻

索引文件中的 a2.id 這個列 會把全部數據 從大到小排序 即 1 - 5000

那麼在聯表時 當 a2.id 的 1號跟 a1.id 1號相匹配以後 明確知道 接下來在a2.id 中在沒有 1號了 直接會跟

a1.id 的2號開始匹配 一次類推 結果 他只匹配5000次。

也就是說 在沒有索引的狀況下 上面的聯表會進行 2500萬次的匹配,而設置索引以後 僅匹配 5000次。

因爲上述測試是使用 left join ,事實上只須要給 a2 的 id 加索引就能夠了。給 a1.id 加索引是多餘了。

誰適合加索引? 簡單來講的話 where 條件中的列 或 left join on 列 = 列 時 看聯表方向 此時是 第二個列適合加索引。

那麼誰又不適合加索引呢? 列的數據重複率較高的列和修改率較高的列。

 

緣由是,重複列較高的列,例如 性別,他只有 男 和 女 這2個數據 若是設置了索引,那麼只會增長無用的磁盤空間。

把男女排序了 也就是 男 和 女 這2個數據,設置索引 沒有任何意義。

修改率高的列,上面說過,索引是會排序的,那麼若是把修改率高的列設了索引 那麼每一次修改操做結束以後

索引文件也會從新排列全部數據,這樣以來 雖然在查詢時能提升性能上的問題,可是在修,增的時候並不是如此。

多列索引

若是目前有一個用戶表,分別有 姓名 , 年齡 , 電話 等列 (假設這些列是最常被查詢的)

有一個用戶管理頁中有一個搜索部分 會根據 輸入的 姓名 , 年齡 , 電話 來搜索此人的詳細記錄。

 

那麼這個時候到底給那一個列加索引比較好呀? (由於mysql一次只能使用一個索引,據我瞭解)

此時可使用多列索引

alter table user add index user_age_phone(user , age , phone)

建立多列索引以後 如查詢

where user='abc' and age = 25 and phone = 1234

mysql 直接會匹配 user = 'abc' 這一項 在去匹配 age = 25 這一項 接着去匹配 phone 這同樣,三個條件 僅僅3次匹配就獲得結果了。

那麼若是不使用多列索引的話 咱們也只能給其中的一項列建立索引,假設 咱們給 user 列建立了索引,那麼當執行上述查詢以後

由於 user 被設有索引 所以 找到 abc 只須要一次匹配 以後的操做 他首先會排除 年齡不是 25歲的記錄 在去排除 電話不是 1234 的記錄。

這麼以來 雖然 比 沒有任何索引的狀況好了不少 可是最終查詢結果並不是是理想。

至於什麼列須要家索引,什麼列不須要加索引 只能在實際狀況中分析了。


 【索引的使用】

在一下幾種狀況下 mysql 在查詢中即便有索引也不會去使用

1:在多列索引,查詢條件中用的不是最座標的列,那麼此時是不會使用索引。

2:like查詢時 % 出如今第一位也不會使用索引

3:條件中有 or 也不會使用索引。

4:索引列類型是字符串,可在查詢中省略了 引號(有時字符串類型列也會存儲數字),此時不會使用索引

5:若是 mysql 估計使用全表掃描比使用索引快,他也不會使用索引。

【如何檢測所建立的索引是否有效(或者說索引使用狀況)】

show status like 'Handler_read%'

 Handler_read_key 越高越好

Handler_read_rnd_next 越高越很差

相關文章
相關標籤/搜索