Mysql性能優化筆記
一,索引
1.Innodb索引使用的是B+樹
2.盡量簡化where條件,比如不要出現 where id + 3 = 5,這無法使用索引
3.索引很大時,可以冗余一列來模擬哈希索引
4.小的表不需要使用索引,很大的表需要用分塊技術,也不用索引
5.索引的選擇性=不重復的數量/總的數量
選擇性越高,效率越高,unique索引選擇性為1,效率最好
對於blob,text,很長的varchar類型的列,必須使用前綴索引。
訣竅在於,要選擇足夠長的前綴以保證較高的選擇性,同時又不能太長
創建前綴索引:(city列裏長度為7的前綴索引)
alter table sakila.city_demo ADD KEY(city(7))
前綴索引的缺點,無法做ORDER BY和GROUP BY
後綴索引:mysql不支持反向索引,但可以把字符串反轉後存儲,並基於此建立索引,可以通過觸發器來維護索引
6、多列索引
對多個列做相交操作(and)時,需要的時一個多列索引而不是多個單獨的單列索引
如果在explain中看到有索引合並,應該好好檢查一下查詢和表單結構,
可以通過參數optimizer_switch來關閉索引合並
7.覆蓋索引
如果一個索引包含所有需要查詢的字段的值,我們就稱之為覆蓋索引
由於myISAM在內存中只存索引,所以用覆蓋索引有嚴重的性能問題
由於InnoDB的聚簇索引,覆蓋索引對InnoDB特別有用
另外,只能用B-tree索引做全文索引
當使用覆蓋索引時,EXPLAIN 中的Extra中顯示Using index
查詢優化
一般的優化方法有兩個
1.確認應用程序是否在檢索大量超過需要的數據,這通常意味著訪問了太多的行
但有時候也可能是訪問了太多的列
2.確認MySQL服務器層是否在分析大量超過需要的數據行
解決方法,加limit,
如果數據庫資源緊張,可以考慮用mybatis代替hibernate
取出全部列,會讓優化器無法完成覆蓋索引掃描這類優化,比如hibernate
不過獲取所有列的查詢緩存,比多個獨立的只獲取部分列的查詢緩存更有好處
每次看到select * 請去懷疑一下是否真的需要全部取出
重復查詢相同的數據:請把這個數據緩存起來,比如放到session中
最簡單的衡量查詢開銷的三個指標:
響應時間,
掃描的行數
返回的行數
這三個指標都會記錄到mysql的慢日誌中,所以檢查慢日誌
如果發現查詢需要掃描大量的數據行,但返回少量的行,那麽可以嘗試下面的技巧去優化它
1,使用索引覆蓋掃描,把所有需要用的列都放到索引中
2.改變表結構,例如使用單獨的匯總表
3.重寫這個查詢,各種優化
有時可以考慮將一個復雜查詢分為多個小查詢,如果能減少工作量的話
比如刪除舊的數據,每次刪一點,可以避免一次鎖住很多數據
分解關聯查詢的好處
1、緩存效率更高
2、用返回的數據的id來進行順序查詢比用join進行隨機關聯效率更高
壞處:一條語句分多條,增加連接開銷
排序優化
無論如何,排序都是一個成本很高的操作,所以從性能角度考慮,盡可能避免排序,或避免對大量數據進行排序
Mysql性能優化筆記