在互聯網公司MySQL的使用很是普遍,你們常常會有MySQL性能優化方面的需求。整理了一些在MySQL優化方面的實用技巧。緩存
整數一般是標識列最好的選擇,由於它們很快而且可使用AUTO_INCREMENT
性能優化
徹底「隨機」的字符串(如:MD5()
、SHA1()
或者UUID()
等產生的字符串)會任意分佈在很大的空間內,會致使INSERT
以及一些SELECT
語句變的很慢服務器
若是但願查詢執行得快速且併發性好,單個查詢最好不要作太多的關聯查詢(互聯網公司很是忌諱關聯查詢),利用程序來完成關聯操做併發
若是須要對一張比較大的表作表結構變動(ALTER TABLE
操做增長一列),建議先拷貝一張與原表結構同樣的表,再將數據複製進去,最後經過重命名將新表的表名稱修改成原表的表名稱。由於在變動表結構的時候頗有可能會鎖住整個表,而且可能會有長時間的不可用函數
避免多表關聯的時候能夠適當考慮一些反範式的建表方案,增長一些冗餘字段性能
若是不是按照索引的最左列開始查找,則沒法使用索引學習
全部的非聚簇索引都須要先經過索引定位到對應的主鍵,而後在到聚簇索引查找數據,因此在定義主鍵索引的時候必定要謹慎優化
只有當索引的列順序和ORDER BY
子句的順序徹底一致,而且全部列的排序方向(倒序或者正序)都同樣時,MySQL纔可以使用索引來對結果作排序。有一種狀況下ORDER BY
子句能夠不知足索引的最左前綴的要求,就是前導列爲常量的時候。設計
在使用like
來匹配字符串類型的字段的值時,儘量的使用前綴匹配like ‘XX%’
,避免使用 like ‘%XX’
code
哈希索引是基於哈希表實現的,只有精確匹配索引全部列的查詢纔有效,也不遵循索引的最左匹配原則
當服務器須要對多個索引作聯合操做時(一般有多個OR
條件),建議修改爲UNION
的方式,這樣方便命中索引
對於如何選擇索引的列順序有一個經驗法則:將選擇性最高的列放到索引最前列
儘量多的使用覆蓋索引(若是一個索引包含或者說覆蓋全部須要查詢的字段的值,咱們就稱之爲覆蓋索引),經過EXPLAIN
的Extra
列能夠看到「Using index」信息
當ID爲主鍵時,建立索引(A),至關於建立了(A)和(A, ID)兩個索引
表中的索引越多對SELECT
、UPDATE
和DELETE
操做速度變慢,同時佔用的內存也會比較多
InnoDB在二級索引上使用共享鎖,可是訪問主鍵索引須要排他鎖
儘量的使用WHERE IN
和WHERE BETWEEN AND
的方式來進行範圍查詢
LIMIT
的偏移量越大性能越慢
編寫查詢語句時應該避免單行查找、儘量的使用數據原生順序從而避免額外的排序操做,並儘量使用索引覆蓋查詢
對於低效的查詢,一般從兩個方面來分析:
通常MySQL可以使用如下三種方式應用WHERE
條件,從好到壞依次爲:
MySQL從設計上讓鏈接和斷開鏈接都很輕量級,在返回一個小的查詢結果方面很高效。在一個通用服務器上,也可以運行每秒超過10萬的查詢,一個千兆網卡也能輕鬆知足每秒超過2000次的查詢,MySQL內部每秒可以掃描內存中上百萬行數據
在刪除大量數據時,建議每次刪除一小批量數據後,暫停一下子再作下一次的刪除
不管如何排序都是一個成本很高的操做,因此從性能角度考慮,應儘量避免排序或者儘量避免對大量數據進行排序
COUNT()
函數有兩種不一樣的做用:它能夠統計某個列值的數量,也能夠統計行數。最簡單的就是經過COUNT(*)
來統計行數
關聯查詢的時候要確保關聯的字段上有索引
在數據量很大而且歷史數據須要按期刪除的狀況下,能夠考慮使用分區表
若是定了的索引列和分區列不匹配,會致使查詢沒法進行分區過濾
外鍵約束儘量避免,一般經過程序來實現,心中要有外鍵
觸發器、存儲過程、自定義函數等最好不要使用
儘量的利用查詢緩存,若是在寫查詢語句的時候有一些不肯定的數據(NOW()
或者CURRENT_DATE()
等)時,則不會被緩存
用多個小表代替一個大表對查詢緩存有好處
批量寫入時只須要作一次緩存失效,因此相比單條寫入(每寫入一次,緩存就失效)效率更好,對於寫密集型的應用,直接禁用查詢緩存
若是緩存的空間太大,在過時操做的時候可能會致使服務器僵死
以上是我的在工做中的經驗總結,若是有描述錯誤的地方但願你們能夠幫忙指出,一塊兒交流學習!