MySQL高級之第二天: 性能下降及索引

(一) MySQL性能下降

也許在現在大家的數據庫表存儲數據還停留在幾千條, 幾萬條的樣子, 所以編寫一般的正確的SQL語句在性能上完全看不出有什麼瑕疵, 而當數據到達了三百萬條左右及以上時, 類似於 "select * from table where condition"的操作會暴露出性能下降的問題, 下面首先來討論一下MySQL性能下降的原因 :  

執行時間長、等待時間長:

    1. 查詢語句寫的爛:各種連接,各種子查詢導致不能用索引,或者沒有建立索引。

    2. 索引失效:建了索引沒用上。

    3. 關聯查詢太多join(設計缺陷或不得已的需求)

    4. 服務器調優及各個參數設置(緩衝、線程數等)


(二) 索引[重要!]

1. 首先我們先來認識索引是什麼?

索引(Index)是一種幫助MySQL高效獲取數據的數據結構

索引的本質: 它是一種數據結構, 不是數據!

 

2. 索引的目的

提高查詢效率, 可以類比到字典上, 索引用於"排序" 和 "快速查找" !

 

例子(有助於你理解索引的作用) : 

如果要查"mysql"單詞, 我們肯定要定位到m字母, 繼續往下找到y字母, 再找剩下的mysql

如果沒有索引,那麼你可能需要a----z,一個個查找.

如果建立了索引, 可以快速直接定位到字母m, y, s, q, l這幾個字母.

 

3. 索引的優勢和劣勢

3.1 優勢:

1. 大學圖書館建立書目索引, 提高數據檢索的效率, 降低數據庫的IO成本(IO)

2. 通過索引列對數據進行排序,降低數據排序的成本, 降低了CPU的消耗.(運算CPU)

3.2 劣勢:

1. 實際上索引也是一張表, 該表保存了主鍵和索引字段, 並指向實體表的記錄, 所以索引也是要佔空間的

2. 雖然索引大大提高了查詢速度,同時卻會降低更新表的速度, 例如對錶進行INSERT, UPDATE和DELETE. 因爲更新表時, MySQL不僅要保存數據, 還要保存一下索引文件每次更新添加了索引列的字段, 都會調整因爲更新所帶來的鍵值變化後的索引信息

3. 索引只是提高效率的一個因素, 如果你的MySQL有大數據量的表, 就需要花時間研究建立最優秀的索引, 或優化查詢.

4. 索引分類和建索引命令語句

4.1 索引可分爲以下兩種類型:

1. 單值索引:

一個索引只包含單個列, 一個表可以有多個單列索引.

一張表最多的索引不要超過五個

例子:

select * from user where name = '';

create index idx_user_name on user(name);

 

2. 複合索引:

即一個索引包含多個列

例子:

select * from user where name = '' and email='';

create index idx_user_nameEmail on user(name, email);   

 

3. 唯一索引:

    索引列的值必須唯一,但允許有空值.(銀行數據表裏的銀行卡號)

 

4. 基本語法:

創建: CREATE [UNIQUE] INDEX indexName ON myTbale(columnName(length));

ALTER myTable ADD [UNIQUE] INDEX [indexName] on (columnName(length))

 

刪除: DROP INDEX [indexName] on myTable;

 

查看: SHOW INDEX FROM table_name\G

 

使用ALTER命令:

1.ALTER TABLE tbl_name ADD PRIMARY KEY(column_list);

該語句添加一個主鍵, 這意味着索引值必須是唯一的, 且不能爲NULL

 

2.ALTER TABLE tbl_name ADD UNIQUE index_name(column_list)

該語句創建唯一索引(除了NULL外, NULL可能會出現多次)

 

3.ALTER TABLE tbl_name ADD INDEX index_name(column_list);

該語句創建普通索引, 索引值可出現多次.

 

4. ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list);

該語句指定了索引爲FULLTEXT, 用於全文索引

構造索引的索引名格式:idx_表名_字段名 on 表名(字段名);

5. MySQL索引結構

主攻BTree索引,知道還有Hash索引, full-text全文索引, R-Tree索引

BTree檢索原理

 

 

6. 哪些情況需要創建索引?

1. 主鍵自動建立唯一索引.

2. 頻繁作爲查詢條件的字段應該創建索引

3. 查詢中與其它表關聯的字段, 外鍵關係建立索引

4. 頻繁更新的字段不適合創建索引

5. Where條件裏用不到的字段不創建索引

6. 單鍵/組合索引的選擇問題, who?(在高併發下傾向於創建組合索引)

7. 查詢中排序的字段, 排序字段若通過索引去訪問將大大提高排序速度(order by 排序字段)

8. 查詢中統計或分組字段(group by 分組字段)

 

7. 哪些情況不適合創建索引?

1. 表記錄太少(300萬條以上數據,MySQL性能開始下降)

2. 經常在增刪改的表(因爲提高了查詢速度, 同時卻會降低更新表的速度, 如對錶進行INSERT, UPDATE, 和DELETE.因爲更新表時, MySQL不僅要保存數據, 還要保存一下索引文件)

3. 注意, 如果某個數據列包含許多重複的內容, 爲它建立索引就沒有太大的實際效果.(男/女 中國國籍)

例子: 假如一個表有10萬行記錄, 有一個字段A只有True和False兩種值, 且每個值得分佈概率大約爲50%, 那麼對這種表A字段建立索引一般不會提高數據庫的查詢速度.

索引的選擇性是指索引列中不同值得數目與表中記錄數的比. 如果一個表中有2000條記錄, 表索引列有1980個不同的值, 那麼這個索引的選擇性就是1980/2000 = 0.99. 一個索引的選擇性越接近於1, 這個索引的效率就越高.

 

今天就記錄這麼多吧, 主要是讓大家理解MySQL性能下降的原因還有索引相關的基礎知識, 希望能與你們一起進步!如有疑問可以留言, 我很樂意與你們交流!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章