(一) 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性能下降的原因還有索引相關的基礎知識, 希望能與你們一起進步!如有疑問可以留言, 我很樂意與你們交流!