1,MySQL版本:
- MySQL Community Server 社區(qū)版本鹅士,開源免費(fèi)券躁,但不提供官方技術(shù)支持。
- MySQL Enterprise Edition 企業(yè)版本,需付費(fèi)也拜,可以試用30天以舒。
- MySQL Cluster 集群版,開源免費(fèi)慢哈÷樱可將幾個MySQL Server封裝成一個Server。
- MySQL Cluster CGE 高級集群版卵贱,需付費(fèi)滥沫。
- MySQL Workbench(GUI TOOL)一款專為MySQL設(shè)計(jì)的ER/數(shù)據(jù)庫建模工具。它是著名的數(shù)據(jù)庫設(shè)計(jì)工具DBDesigner4的繼任者键俱。MySQL Workbench
又分為兩個版本兰绣,分別是社區(qū)版(MySQL Workbench OSS)、商用版(MySQL Workbench SE)编振。
MySQL Community Server 是開源免費(fèi)的缀辩,這也是我們通常用的MySQL的版本。根據(jù)不同的操作系統(tǒng)平臺細(xì)分為多個版本党觅,
5.X:
5.0-5.1:早期產(chǎn)品的延續(xù)雌澄,升級維護(hù)
5.4 - 5.x :MySQL整合了第三方公司的新存儲引擎 (5.5 5.7)
https://blog.csdn.net/vtopqx/article/details/87934889
2,mysql邏輯分層:連接層杯瞻,服務(wù)層,引擎層炫掐,存儲層
https://www.cnblogs.com/sunjingwu/p/9732371.html
3魁莉,存儲引擎
- inndb
事務(wù)有限 行鎖 - myisam
性能優(yōu)先 表鎖
查看當(dāng)前的存儲引擎:
show engines ;
show variables like '%storage_engine%'
4,SQL優(yōu)化
原因:SQL問題(鏈接查詢)募胃,索引失效旗唁,服務(wù)器參數(shù)設(shè)置問題(緩沖區(qū),線程數(shù)設(shè)置不合理)
1痹束,SQL:解析過程检疫,from,on祷嘶,join屎媳,where, group by论巍, having. select, order by ,limit SQL解析過程
2烛谊,SQL優(yōu)化,主要就是優(yōu)化索引
3嘉汰,什么是索引:相當(dāng)于書的目錄丹禀,索引是幫助MySQL高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu) ,索引是數(shù)據(jù)結(jié)構(gòu)(默認(rèn)B樹)
4,索引本身很大双泪,需要占用內(nèi)存和硬盤持搜。不是所有情況都適用,頻繁更新的字段不適合
建立索引會降低增刪改的效率
B樹:https://www.bilibili.com/video/av36069871?from=search&seid=1181095641637380064
5焙矛,索引
- 單值索引:單列葫盼,一個表內(nèi)可以多個單值索引
- 唯一索引:不能重復(fù)
- 復(fù)合索引:多個列構(gòu)成的索引
6,SQL性能問題
1薄扁,分析SQL的執(zhí)行計(jì)劃:explain 可以模擬SQL優(yōu)化器執(zhí)行SQL語句
- explain + sql語句 查詢執(zhí)行計(jì)劃
- select_type :查詢類型
- table :表
- type :類型
- possible keys :預(yù)測用到的索引
- key: 實(shí)際使用的索引
- key_len :實(shí)際使用索引的長度
- ref:表之間的引用
- rows:通過索引查到的數(shù)據(jù)量
- extra:額外的信息
2剪返,explain詳解:
id:
值相同 從上往下,順序執(zhí)行
多表內(nèi)連接查詢邓梅,表執(zhí)行順序脱盲,因數(shù)量的個數(shù)改變而改變的原因:笛卡爾積
數(shù)據(jù)小的表,優(yōu)先查詢
id值不同日缨,越大越優(yōu)先查詢
select_type
- primary 包含子查詢SQL中的主查詢(最外層)
- subquery 包含子查詢SQL中的子查詢(非最外層)
- simple:簡單查詢钱反,不包含子查詢,union
- derived:衍生查詢匣距,查詢的時(shí)候用到了臨時(shí)表
- from 子查詢 中只有一張表面哥,臨時(shí)表 select * from(select * from t where t.id in (1,2))tr
- 在from 子查詢中,如果有兩張 兩張表 union查詢毅待,則前面的查詢是衍生查詢尚卫,第二張表則叫union ,
select * from(select * from t where t.id = 1 union select * from t where t.id = 2)tr - union:union查詢的除最左表的右表則是union查詢
- union Result:指union 連接出來的臨時(shí)表
type
越左性能越好
system> const>eq_ref>ref>range>index>all
system,const 只是理想情況,實(shí)際能達(dá)到ref>range
要對type進(jìn)行優(yōu)化的前提 是有索引
system:只有一條數(shù)據(jù)的系統(tǒng)表尸红,或衍生表只有一條數(shù)據(jù)的主查詢(select * from (select * from t ) t where id = 1) t表只有一條數(shù)據(jù)
const:僅僅能查到一條數(shù)據(jù)的SQL吱涉,用于primary key 或unique 索引
eq_ref:唯一性索引,對于每個索引鍵的查詢外里,返回匹配唯一行數(shù)據(jù)怎爵,有且只能有一條數(shù)據(jù)
常見于唯一索引,和主鍵索引ref:非唯一性盅蝗,對于每個索引鍵的查詢鳖链,返回匹配的所有行(0,多)
select * from t where name = 'zs' zs 不唯一range:檢索指定范圍的行墩莫,where 后面是范圍查詢(between芙委,in ,> < )in可能會失效變成無索引all
index:查詢?nèi)克饕袛?shù)據(jù)
all:查詢?nèi)勘頂?shù)據(jù)
type——小結(jié)
system/const:結(jié)果只有一條數(shù)據(jù)
eq_ref:結(jié)果多條贼穆,但是每條數(shù)據(jù)是唯一的
ref:結(jié)果多條题山,每條數(shù)據(jù)可以是0或者多條
possible_keys
可能用到的索引。預(yù)測用到的索引
key
實(shí)際使用到的索引故痊, 如果是null 則是沒有索引
key_len
索引長度:用于判斷符合索引是否被完全使用
utf8 一個字符 3個字節(jié) 一個字節(jié)表示可以為null 兩個字節(jié)表示可變長度
ref
指明當(dāng)前表所 參照的字段顶瞳,常量列 const,=‘’等于某個常量
引用字段 t.id = c.id
rows
行數(shù),被索引優(yōu)化查詢的數(shù)據(jù)個數(shù)慨菱,通過條件查詢出來的數(shù)據(jù)個數(shù)
extra
using filesort:性能消耗大焰络,需要額外一次排序(查找) where a='' order by b 常見于order by
對于單索引,如果排序和查找是同一個字段則不會出現(xiàn)using filesort符喝,反之
復(fù)合索引闪彼,不能跨列,并且最佳最前綴
單索引:where 什么字段 order by什么字段
復(fù)合索引:where 和 order by按照復(fù)合索引的順序使用协饲,不要跨列或無序使用using temporary 性能損耗大畏腕,用到臨時(shí)表,
一般出現(xiàn)group by 中茉稠,出現(xiàn)在select a2 from t group by a1
避免:where什么列描馅,就根據(jù)哪些列g(shù)roup byusing index:性能提升,索引覆蓋而线。
不讀取源文件铭污,只從索引文件中獲取數(shù)據(jù),不需要回表查詢
(不回表查詢:如果 select age from t where age = 1 膀篮,假設(shè)age是索引列嘹狞,那么只需要到索引樹當(dāng)中查詢數(shù)據(jù)不需要回表查詢其他的數(shù)據(jù))
出現(xiàn)不回表查詢則出現(xiàn)using index,
如果索引覆蓋 (using index) 會對possible_keys 和 keys造成影響
如果沒有where誓竿,則索引只出現(xiàn)在key中
如果有where磅网,則出現(xiàn)在key 和 possible_keys中
using where:需要回表查詢,則會出現(xiàn)using where
select age,name from where age = 1 筷屡,假設(shè)age是索引知市,則此語句需要回表查詢會出現(xiàn)using whereimpossible where:where 字句永遠(yuǎn)為false
3,SQL優(yōu)化:
復(fù)合索引不能跨列速蕊,否則索引失效,可以通過key_len 來觀察是否使用到索引
補(bǔ)充using filesort:復(fù)合索引不要跨列使用(where 和 order by 拼起來)沒有跨列
where 和 order by 拼起來是否滿足復(fù)合索引順序娘赴,滿足則不會出現(xiàn)using filesort反之
1规哲,如果(a,b,c,d)復(fù)合索引 和使用的順序全部一致,則復(fù)合索引全部使用诽表,如果部分一致
則使用部分索引 select a,c where a = and b= and c= and d= 和索引順序完全一致(不跨列使用)則復(fù)合索引全部使用
2唉锌,單表優(yōu)化:根據(jù)SQL實(shí)際的解析順序,調(diào)整復(fù)合索引的順序(最佳左前綴)
索引需要逐步優(yōu)化竿奏。將含in的范圍查詢放到where 的最后防止失效袄简,失效則會導(dǎo)致后面的索引失效,并且需要回原表查詢
3泛啸,多表優(yōu)化:小表驅(qū)動大表绿语,索引建立在經(jīng)常使用的字段上,左外連接 給外表加索引。
4吕粹,避免索引失效的原則
(SQL優(yōu)化是一種概率事件种柑,并不一定達(dá)到預(yù)想情況)失效的情況大部分適用
索引優(yōu)化 是一個大部分情況適用的結(jié)論,但由于SQL優(yōu)化器等原因匹耕,結(jié)論不是百分百正確
一般情況聚请,范圍查詢(>< in),之后的索引失效
盡量使用索引覆蓋稳其,索引不會失效(using index)
in 會使索引失效驶赏,
復(fù)合索引不要跨列(where+order by拼接起來 ),或者無序使用(最佳最前綴)
復(fù)合索引盡量使用全索引匹配
不要在索引上進(jìn)行任何操作既鞠,比如計(jì)算煤傍,函數(shù)。否則索引失效
復(fù)合索引只要左邊有一個失效則右邊的索引全部失效
復(fù)合索引不能使用 不等于损趋,is null患久,is not null。否則自身已經(jīng)右側(cè)索引全部失效
like 盡量以常量開頭浑槽,不要以%開頭蒋失,否則索引失效
盡量不要包含類型轉(zhuǎn)換(顯示,隱式)varchar 字段 = 123 桐玻。存在隱式轉(zhuǎn)換
盡量不要使用or 篙挽,否則索引失效
5,SQL優(yōu)化方法镊靴。
1铣卡,exist 和 in 如果主查詢的數(shù)據(jù)集大用 in,如果子查詢數(shù)據(jù)集大偏竟,則使用exist
2煮落,order by,經(jīng)秤荒保看到using filesort 有兩種算法蝉仇,雙路排序和單路排序,根據(jù)IO的次數(shù)
- 雙路排序:雙路:掃描兩次磁盤殖蚕。第一次掃描排序字段轿衔,排序在buffer 緩沖區(qū)進(jìn)行排序,第二次掃描其他字段
- 單路排序:只讀取一次(全部字段)睦疫,在buffer中進(jìn)行排序害驹,但此種單路排序會有一定的隱患,不一定真的是“單路”1次IO蛤育,有可能多次IO
如果數(shù)據(jù)量特別大宛官,則無法將所有字段的數(shù)據(jù)讀取完畢葫松,進(jìn)行分片讀取,多次讀取摘刑。單路排序比雙路排序占用更多的buffer緩沖區(qū)
可以考慮buffer的容量大薪Α:set max_length_for_sort_data = 1024(字節(jié))
如果set max_length_for_sort_data值太低,則MySQL會自動從 單路排序切換到雙路排序枷恕。(太低:需要排序列的總大小超過了max_length_for_sort_data定義的字節(jié)數(shù))
提高order by查詢的策略:選擇使用單路党晋,雙路;調(diào)整buffer的容量大小徐块,避免select * 未玻,保證全部的排序字段 排序的一致性(都是升序 或 降序)
6,SQL排序-慢查詢?nèi)罩?/h4>
MYSQL提供的日志記錄胡控,用于記錄MySQL響應(yīng)時(shí)間超過閾值的SQL語句(long_query_time扳剿,默認(rèn)十秒)
慢查詢?nèi)罩灸J(rèn)是關(guān)閉的,建議昼激,開發(fā)調(diào)優(yōu)時(shí)打開庇绽,而在最終部署時(shí)關(guān)閉。
檢查是否開啟慢查詢?nèi)罩荆簊how variables like '%slow_query_log%'橙困,
開啟慢查詢?nèi)罩?/strong>
1瞧掺,臨時(shí)開啟:set global slow_query_log = 1 內(nèi)存中開啟
2,永久開啟:/etc/my.cnf 中追加配置 [mysqld] slow_query_log=1 slow_query_log_file=日志路徑
慢查詢閾值:show variables like '%long_query_time%'
1凡傅,臨時(shí)設(shè)置:set global long_query_time辟狈,設(shè)置完畢重新登錄
2,永久設(shè)置:/etc/my.cnf 中追加配置[mysqld] long_query_time=3
查詢超過閾值的SQL條數(shù):show global status like '%slow_queries%'
通過日志查看具體的慢SQL夏跷,通過mysqldumpslow工具
7哼转,分析海量數(shù)據(jù)
- show variables like '%profiling%'
set profiling = no 開啟
show profiles; 會記錄所有profiling 打開后所有執(zhí)行的語句所花費(fèi)的時(shí)間。只能看到總共消費(fèi)時(shí)間槽华。 - 精確分析:sql 診斷
show profile all for query 查詢到的SQLid - 全局查詢?nèi)罩荆河涗涢_始之后的 全部SQL語句壹蔓。(調(diào)優(yōu)過程中打開)
show variables like '%general_log%' set global general_log = 1,set global log_output='table'
開啟全局日志 開啟之后記錄所有SQL猫态,會被記錄到MySQL general_log 表中