本文主要是總結了工作中一些常用的操作,以及不合理的操作,在對慢查詢進行優化時收集的一些有用的資料和信息,本文適合有MySQL基礎的開發人員。
一、索引相關
索引基數:基數是數據列所包含的不同值的數量。例如,某個數據列包含值1、3、7、4、7、3,那么它的基數就是4。索引的基數相對于數據表行數較高(也就是說,列中包含很多不同的值,重復的值很少)的時候,它的工作效果最好。如果某數據列含有很多不同的年齡,索引會很快地分辨數據行。如果某個數據列用于記錄性別(只有"M"和"F"兩種值),那么索引的用處就不大。如果值出現的幾率幾乎相等,那么無論搜索哪個值都可能得到一半的數據行。在這些情況下,最好根本不要使用索引,因為查詢優化器發現某個值出現在表的數據行中的百分比很高的時候,它一般會忽略索引,進行全表掃描。慣用的百分比界線是"30%"。
索引失效原因:
對索引列運算,運算包括(+、-、*、/、!、、%、like'%_'(%放在前面)類型錯誤,如字段類型為,where條件用。
對索引應用內部函數,這種情況下應該建立基于函數的索引如 * from t where ROUND(t.) = 1
此時應該建ROUND(t.)為索引,.0開始支持函數索引,5.7可以通過虛擬列的方式來支持,之前只能新建一個ROUND(t.)列然后去維護
索引的建立
最重要的是根據業務經常查詢的語句盡量選擇區分度高的列作為索引,區分度的公式是 COUNT( col) / COUNT(*)。表示字段不重復的比率,比率越大我們掃描的記錄數就越少。如果業務中唯一特性最好建立唯一鍵,一方面可以保證數據的正確性,另一方面索引的效率能大大提高
二、中有用的信息
基本用法
提高性能的特性
extra字段
1. using : 說明MySQL會對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取。MySQL中無法利用索引完成的排序操作稱為“文件排序” ,其實不一定是文件排序,內部使用的是快排
2. using : 使用了臨時表保存中間結果,MySQL在對查詢結果排序時使用臨時表。常見于排序order by和分組查詢group by
3. using index: 表示相應的操作中使用了覆蓋索引( Index),避免訪問了表的數據行,效率不錯。
6. where: WHERE子句的值總是false,不能用來獲取任何元組
7. away: 在沒有GROUP BY子句的情況下基于索引優化MIN/MAX操作或者對于存儲引擎優化COUNT(*)操作, 不必等到執行階段再進行計算,查詢執行計劃生成的階段即完成優化
8. : 優化操作,在找到第一匹配的元祖后即停止找同樣值的操作
注:using ,using 這兩項出現時需要注意下,這兩項是十分耗費性能的,在使用group by的時候,雖然沒有使用order by,如果沒有索引,是可能同時出現using ,using 的,因為group by就是先排序在分組,如果沒有排序的需要,可以加上一個order by NULL來避免排序,這樣using 就會去除,能提升一點性能。
type字段
三、字段類型和編碼
mysql返回字符串長度:方法(一樣的)返回的是字符數,函數返回的是字節數,一個漢字三個字節
等字段建立索引長度計算語句: count( left(test,5))/count(*) from table; 越趨近1越好
mysql的utf8最大是3個字節不支持emoji表情符號,必須只用。需要在mysql配置文件中配置客戶端字符集為。jdbc的連接串不支持配置=mysql 查看當前時間,最好的辦法是在連接池中指定初始化sql,例如:連接池,其他連接池類似...-init-sql=set names 。否則需要每次執行sql前都先執行set names 。
msyql排序規則(一般使用_bin和):
不區分大小寫,ci為case 的縮寫,即大小寫不敏感,
區分大小寫,cs為case 的縮寫,即大小寫敏感,但是目前
MySQL版本中已經不支持類似于***的排序規則,直接使用替代。
將字符串中的每一個字符用二進制數據存儲,區分大小寫。
那么,同樣是區分大小寫,和有什么區別?
cs為case 的縮寫,即大小寫敏感;bin的意思是二進制,也就是二進制編碼比較。
排序規則下,即便是區分了大小寫,但是某些西歐的字符和拉丁字符是不區分的,比如?=a,但是有時并不需要?=a,所以才有
的特點在于使用字符的二進制的編碼進行運算,任何不同的二進制編碼都是不同的,因此在排序規則下:?a
sql yog中初始連接指定編碼類型使用連接配置的初始化命令
四、SQL語句總結
常用的但容易忘的:
鎖相關(作為了解,很少用)
共享鎖: id from where id = 1 lock in share mode;
排它鎖: id from where id = 1 for
優化時用到:
強制使用某個索引: * from table force index() limit 2;
禁止使用某個索引: * from table index() limit 2;
禁用緩存(在測試時去除緩存的影響): from table limit 2;
查看狀態
SQL編寫注意
五、踩坑
六、千萬大表在線修改
mysql在表數據量很大的時候,如果修改表結構會導致鎖表,業務請求被阻塞。mysql在5.6之后引入了在線更新,但是在某些情況下還是會鎖表,所以一般都采用pt工具( )
如對表添加索引:
pt-online-schema-change --user='root' --host='localhost' --ask-pass --alter "add index idx_user_id(room_id,create_time)" D=fission_show_room_v2,t=room_favorite_info --execute
七、慢查詢日志
有時候如果線上請求超時,應該去關注下慢查詢日志,慢查詢的分析很簡單,先找到慢查詢日志文件的位置,然后利用去分析。查詢慢查詢日志信息可以直接通過執行sql命令查看相關變量,常用的sql如下:
-- 查看慢查詢配置
-- 慢查詢日志是否開啟
-- 的值是記錄的慢查詢日志到文件中
-- 指定了慢查詢的閾值
-- 是否記錄所有沒有利用索引的查詢
SHOW LIKE '%quer%';
-- 查看慢查詢是日志還是表的形式
SHOW LIKE ''
-- 查看慢查詢的數量
SHOW LIKE '';
的工具十分簡單,我主要用到的是參數如下:
例子: -v -s t -t 10 .log.2018-11-20-0500
八、查看sql進程和殺死進程
如果你執行了一個sql的操作,但是遲遲沒有返回,你可以通過查詢進程列表看看他的實際執行狀況mysql 查看當前時間,如果該sql十分耗時,為了避免影響線上可以用kill命令殺死進程,通過查看進程列表也能直觀的看下當前sql的執行狀態,如果當前數據庫負載很高,在進程列表可能會出現,大量的進程夯住,執行時間很長。命令如下:
--查看進程列表
SHOW ;
--殺死某個進程
kill
如果你使用的,那么也有圖形化的頁面,在菜單欄-工具-顯示-進程列表。在進程列表頁面可以右鍵殺死進程。如下所示:
查看進程列表
殺死進程
九、一些數據庫性能的思考
在對公司慢查詢日志做優化的時候,很多時候可能是忘了建索引,像這種問題很容易解決,加個索引就行了。但是有兩種情況就不是簡單能加索引能解決了:
原文:
李翔宇
張維照
崔虎龍
姜勁松
劉晨
章芋文
蘭珊
李晴晴
盧立廣
張甦
李亮
陳龍
老張拉呱
李敏
趙靖宇
廖學強
何劍敏
張樂奕
李真旭
羅海雄
楊廷琨
蓋國強
數據和云專家團
資源下載