應該努力地去生活,對過往閉口不提,是好是壞皆爲經歷。
MySql中索引這部分知識是要去看下會的,特別是對自己有點要求的,因爲索引使用到好的對Sql的查詢語句速度會大大的提升,所以是很有必要去學習的。
MySql 官方對索引的定義
索引(Index)是幫助MySQL高效獲取數據的數據結構。 ----> 推斷出 : 可以得到索引的本質:索引是數據結構。
可以簡單的理解爲 : 排好序的快速查找數據結構
一般來說索引本身也很大,不可能全部存儲在內存中,因此索引往往以索引文件的形式存儲的磁盤上.
聚集索引,次要索引,覆蓋索引,複合索引,前綴索引,唯一索引默認都是使用B+樹索引,統稱索引。當然,除了B+樹這種類型的索引之外,還有哈稀索引(hash index)等。
MySql 索引優勢 :
打個網上都有的比列 :
類似大學圖書館建書目索引,提高數據檢索的效率,降低數據庫的IO成本。通過索引列對數據進行排序,降低數據排序的成本,降低了CPU的消耗
MySql 索引的不足之處
需要佔用空間 : 實際上索引也是一張表,該表保存了主鍵與索引字段,並指向實體表的記錄,所以索引列也是要佔用空間的。
添加修改刪除等 : 雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對錶進行INSERT、UPDATE和DELETE。因爲更新表時,MySQL不僅要保存數據,還要保存一下索引文件每次更新添加了索引列的字段,都會調整因爲更新所帶來的鍵值變化後的索引信息。
索引只是提高效率的一個因素,如果你的MySQL有大數據量的表,就需要花時間研究建立最優秀的索引,或優化查詢語句。
MySql 中索引的介紹
主鍵索引 : 設定爲主鍵後數據庫會自動建立索引,innodb爲聚簇索引.
單值索引 : 即一個索引只包含單個列,一個表可以有多個單列索引
創建語法 : CREATE INDEX idx_test_name ON test(test_name);
刪除語法 : DROP INDEX idx_test_name ;
唯一索引 : 索引列的值必須唯一,但允許有空值
創建語法 : CREATE UNIQUE INDEX idx_test_no ON test(test_no);
刪除語法 : DROP INDEX idx_test_noon test;
符合索引 : 即一個索引包含多個列
創建語法 : CREATE INDEX idx_no_name ON customer(customer_no,customer_name);
刪除語法 : DROP INDEX idx_no_name on customer ;
基本的語法使用 :
創建 : ALTER mytable ADD [UNIQUE ] INDEX [indexName] ON (columnname(length))
刪除 : DROP INDEX [indexName] ON mytable;
查看 : SHOW INDEX FROM table_name\G
添加方式 :
ALTER TABLE tbl_name ADD PRIMARY KEY (column_list):
該語句添加一個主鍵,這意味着索引值必須是唯一的,且不能爲NULL。
ALTER TABLE tbl_name ADD UNIQUE index_name (column_list):
這條語句創建索引的值必須是唯一的(除了NULL外,NULL可能會出現多次)。
ALTER TABLE tbl_name ADD INDEX index_name (column_list):
添加普通索引,索引值可出現多次。
ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):
該語句指定了索引爲 FULLTEXT ,用於全文索引。
一般需要創建索引的情況 和 一般不要創建的
一般需要 :
1 : 主鍵自動建立唯一索引
2 : 頻繁作爲查詢條件的字段應該創建索引(where 後面的語句)
3 : 查詢中與其它表關聯的字段,外鍵關係建立索引
4 : 單鍵/組合索引的選擇問題,who?(在高併發下傾向創建組合索引)
5 : 查詢中排序的字段,排序字段若通過索引去訪問將大大提高排序速度
6 : 查詢中統計或者分組字段
一般不需要 :
1 : 數據量不多的話
2 : 經常增刪改的表 : 提高了查詢速度,同時卻會降低更新表的速度,如對錶進行INSERT、UPDATE和DELETE。因爲更新表時,MySQL不僅要保存數據,還要保存一下索引文件
3 : Where條件裏用不到的字段不創建索引
4 : 數據重複且分佈平均的表字段,因此應該只爲最經常查詢和最經常排序的數據列建立索引。注意,如果某個數據列包含許多重複的內容,爲它建立索引就沒有太大的實際效果。
一般MySql 常見的瓶頸
CPU : SQL中對大量數據進行比較、關聯、排序、分組
IO : 實例內存滿足不了緩存數據或排序等需要,導致產生大量 物理 IO。查詢執行效率低,掃描過多數據行。
鎖 : 不適宜的鎖的設置,導致線程阻塞,性能下降。死鎖,線程之間交叉調用資源,導致死鎖,程序卡住。
對於查詢慢的處理方法
估計慢查詢是我們都很好奇和想去理解或者處理的東西
1 : 慢查詢日誌 :
- MySQL的慢查詢日誌是MySQL提供的一種日誌記錄,它用來記錄在MySQL中響應時間超過閥值的語句,具體指運行時間超過long_query_time值的SQL,則會被記錄到慢查詢日誌中。
- 具體指運行時間超過long_query_time值的SQL,則會被記錄到慢查詢日誌中。long_query_time的默認值爲10,意思是運行10秒以上的語句。
- 由他來查看哪些SQL超出了我們的最大忍耐時間值,比如一條sql執行超過5秒鐘,我們就算慢SQL,希望能收集超過5秒的sql,結合之前explain進行全面分析。
默認情況下,MySQL數據庫沒有開啓慢查詢日誌,需要我們手動來設置這個參數.當然,如果不是調優需要的話,一般不建議啓動該參數,因爲開啓慢查詢日誌會或多或少帶來一定的性能影響。慢查詢日誌支持將日誌記錄寫入文件
查看是否開啓 : SHOW VARIABLES LIKE '%slow_query_log%'; 開啓 : set global slow_query_log=1;
SHOW VARIABLES LIKE 'long_query_time%'; 這是查看設置多少秒才能算的。
show global status like '%Slow_queries%'; 當前系統中有多少慢的Sql
最後說下慢的Sql都會在對應的日誌文件中
2 : Show Profile
- mysql提供可以用來分析當前會話中語句執行的資源消耗情況。可以用於SQL的調優的測量
默認情況下,參數處於關閉狀態,並保存最近15次的運行結果
Show variables like 'profiling'; 查看是否開啓 set profiling=1; 開啓
show profiles 是查看結果
診斷SQL,show profile cpu,block io for query n (n爲上一步前面的問題SQL數字號碼);
3 : 全局查詢日誌
- 在mysql的my.cnf中進行設置
- 開啓 : general_log=1
- 記錄日誌文件路徑 : general_log_file=/path/logfile
- 輸出格式 : log_output=FILE
- set global general_log=1;
- set global log_output='TABLE'; : 全局日誌可以存放到日誌文件中,也可以存放到Mysql系統表中。存放到日誌中性能更好一些,存儲到表中
- select * from mysql.general_log;
- 不建議在生產環境中使用
使用Explain來分析Sql的好壞文章 Explain鏈接地址
加油,堅持學習下去方可不迷失自我。