數(shù)據(jù)庫優(yōu)化的方向:
1瑟押、重啟(重啟是釋放資源的有效方法廓八,例如生產環(huán)境幾年都未重啟過數(shù)據(jù)庫,具體結合自己公司業(yè)務指定重啟計劃)
2窿冯、sql與索引優(yōu)化
3骗奖、表與存儲引擎的優(yōu)化
4、數(shù)據(jù)庫與應用架構的優(yōu)化(分片等)
5、數(shù)據(jù)庫與操作系統(tǒng)配置
6执桌、硬件
索引優(yōu)化:見mysql索引及數(shù)據(jù)庫引擎
mysql查詢執(zhí)行的過程:
1鄙皇、mysql客戶端/服務端通信 -> 2、查詢緩存 -> 3仰挣、查詢優(yōu)化處理 -> 4伴逸、查詢執(zhí)行引擎 -> 5、返回客戶端
1膘壶、mysql客戶端/服務端通信:半雙工通信方式(兩端都可以給對方發(fā)送信息错蝴,但是同一時間只能有一個方向的傳輸)
對于一個mysql連接,或者說一個線程香椎,時刻都有一個狀態(tài)標識這個連接正在做什么
查看命令 show full processlist/ shou processlist
Sleep:線程正在等待客戶端發(fā)送數(shù)據(jù)
Query:連接線程正在執(zhí)行查詢
Locked:線程正在等待表鎖的釋放
Sorting result:線程正在對結果進行排序
Sending data: 向請求端返回數(shù)據(jù)
2漱竖、查詢緩存
使用場景:已讀為主的業(yè)務,數(shù)據(jù)生成之后就不長改變的業(yè)務(新聞畜伐、論壇)
緩存select操作的結果和sql語句
新的select語句馍惹,先去查詢緩存,判斷時候存在可用的記錄
判斷標準:與緩存的sql語句是否完全一致(簡單認為存儲了一個key-value結果玛界,key為sql万矾,value為sql查詢結果集)
show variables like 'query_cache%';
query_cache_type 為0關閉緩存 慎框,為1完全開啟緩存良狈,為2按需開啟緩存(只有帶SQL_CACHE的sql才開啟緩存)
mysql緩存修改語句(set gobal query_cache_type = 0\1\2\),注修改主配置文件要重啟mysql
查詢緩存情況(show status like 'Qcache%')
3、查詢優(yōu)化處理
查詢優(yōu)化分為三個階段:
1解析sql 2預處理階段 3 查詢優(yōu)化器(作用:找到最優(yōu)的執(zhí)行計劃)
執(zhí)行計劃-id:
1笨枯、查詢的序列號薪丁,標識執(zhí)行的順序
2、id不同馅精,如果是子查詢严嗜,id的序號會遞增,id值越大越洲敢,優(yōu)先級越高漫玄,越被先執(zhí)行
3、id相同:從上往下順序執(zhí)行
執(zhí)行計劃-select-type:
SIMPLE:簡單的select查詢压彭,查詢中不包含子查詢或者union
PRIMARY:查詢中包含子查詢部分睦优,最外層查詢被標記為primary
SUBQUERY/METAERIALIZED:SUBQUERY標識在select或者where列表中包含子查詢
METAERIALIZED表示where后面in條件的子查詢
UNION:若第二個select出現(xiàn)在union之后,則被標記為union
UNION RESULT:從union表獲取結果的select
執(zhí)行計劃-table
查詢涉及到的表 <union1,3>1和3指執(zhí)行計劃id
執(zhí)行計劃-type(重要)
訪問類型壮不,sql查詢優(yōu)化中一個很重要的指標汗盘,結果值從好到壞依次是:
system>const>eq_ref>range(好的sql至少要達到這個級別)>index>ALL
執(zhí)行計劃-possible_keys、key询一、 rows衡未、 filtered
possible_keys:查詢過程中可能用到的索引
key實際使用的索引尸执,如果為NULL,則沒有使用索引
rows大致估算出找到所需記錄所需要讀取的行數(shù)
filtered(5.7版本后才有)返回結果的行數(shù)占需要讀到的行數(shù)的百分比缓醋,越大越好
執(zhí)行計劃-Extra(重要的額外信息)
Using filesort :mysql對數(shù)據(jù)使用了外部文件內容進行了排序如失,沒有按照表內的索引進行排序讀取(性能比較差)
Using temporary : 使用了臨時表保存中間結果送粱,常見于order by或group by
Using index:使用了覆蓋索引(效率高)
Using where:使用到了where過濾條件
select tables optimized away :基于索引優(yōu)化min/max或者myisam優(yōu)化count(*)操作
4褪贵、查詢執(zhí)行引擎
調用插件式的存儲引擎的原子ApI的功能進行執(zhí)行計劃的執(zhí)行
5、返回客戶端
1抗俄、有需要緩存的脆丁,執(zhí)行緩存操作
2、增量的返回結果:開始生成第一條結果時动雹,mysql就開始往請求方逐步返回數(shù)據(jù)
好處:mysql服務器無須保存過多的數(shù)據(jù)槽卫,浪費內存,用戶體驗好胰蝠,馬上就拿到數(shù)據(jù)
慢查詢日志配置(定位性能差的sql)
show variables like 'slow_query_log' 顯示慢查詢日志狀態(tài)
set global slow_query_log = on 開始慢查詢日志記錄
set global slow_query_log_file = '/var/lib/mysql/wangzhengxin-slow.log' 設置慢查詢日志記錄位置
set golbal log_queries_not_using_indexes = on 沒有命中索引的全部記錄
golbal_long_query_time = 1:sql執(zhí)行超過1秒歼培,會記錄日志
日志分析:
Time:日志記錄的時間
User@Host:執(zhí)行的用戶及主機
Query_time查詢耗時,Lock_time鎖表時間 茸塞, Rows_sent發(fā)送給請求方的記錄條數(shù) Rows_examined語句掃描的記錄條數(shù)
SET timestamp 語句執(zhí)行的時間點
select .... 執(zhí)行的具體語句
慢查詢日志分析工具
mysqldumpslow
語句(mysqldumpslow -t 10 -s at /var/lib/myssql/gupaoedu-slow.log)
其他工具
mysqlsla躲庄、 pt-query-digest
全局配置文件配置:
最大連接數(shù)配置: max_connections(受mysql系統(tǒng)句柄數(shù)限制(limitnofile)和linux系統(tǒng)句柄數(shù)限制(文件打開數(shù))limits.conf)
內存參數(shù)配置
sort_buffer_size connection排序緩沖區(qū)大小 建議(256k(默認值)->2M之間)
當查詢語句中需要文件排序功能時,馬上為connection分配配置的內存大小
join_buffer_size connection關聯(lián)查詢緩沖區(qū)大小 建議(256k(默認值) -> 1M 之間)
當查詢語句中有關聯(lián)查詢時钾虐,馬上分配配置大小的內存用于這個關聯(lián)查詢噪窘,
上述配置4000鏈接占內存:4000(0.256 + 0.256M) = 2G
innodb_buffer_pool_size(很關鍵) innodb buffer/cache 的大小(默認128K)
緩存的內容:數(shù)據(jù)緩存效扫,索引緩存倔监,緩存數(shù)據(jù),內部結構
大的緩沖池可以減少磁盤I/O次數(shù)菌仁,可以提高性能
參考計算公式:
innodb_buffer_pool_size = (總的物理內存-系統(tǒng)運行所用 - connection)90%
字段設計規(guī)范:必須把字段定義為NOT NULL并且提供默認值
null使用索引浩习,索引統(tǒng)計,值比較都比較復雜掘托,對mysql來說更難優(yōu)化
null會降低數(shù)據(jù)庫性能
null值需要更多的存儲空間
null處理只能使用is null或is not null, 而不能采用 =籍嘹、in闪盔、<、>辱士、<>泪掀、 not in
使用TINYINT 代替枚舉(枚舉底層也是TINYINT )
索引設計規(guī)范:
單表索引建議控制在5個以內
單索引字段數(shù)不超過5個
靜止在更新十分頻繁、離散型低的屬性上建立索引
建立聯(lián)合索引颂碘,必須把區(qū)分高度的字段放在前面
禁止大表使用join
禁止使用or必須改為in(mysql對in做了特別的優(yōu)化)
mysql使用in的話會對in里的內容進行排序异赫,然后二分查找(時間復雜度是O(logN)),用or的話會將滿足條件的記錄會一條一條比對(時間復雜度是O(n))