有關於MySQL的高級部分筆記
這是一篇關於MySQL高級部分的筆記主要是,sql優化以及mysql鎖的相關內容,以及主從配置等內容等比較基礎的優化mysql
1、邏輯架構部分
-
邏輯架構ios
邏輯架構介紹圖以下sql
-
鏈接層:最上層是一些客戶端和鏈接服務,包含本地的sock通信大多時基於客戶端/服務端工具實現的相似於tcp/ip的通信數據庫
-
服務層:完成大多數的核心服務的功能,如,SQL接口,並完成緩存的查詢SQL的分析和優化以及部份內置函數的執行,全部款存儲引擎的功能api
-
引擎層:存儲引擎真正的負責了MySQL中的數據的存儲和提取,服務器經過api與存儲引擎進行通信,經常使用的有MyISAM和InnoDB緩存
-
存儲層:數據存儲在裸設備上,並完成與存儲引擎的交互服務器
優化主要是隻使SQL的解析格式符合優化器的優化格式數據結構
-
存儲引擎架構
查看mysql的存儲引擎命令併發
# 看你的mysql提供了生麼存儲引擎
show engines;
# 看當前默認的存儲引擎
show variables like '%storage_engine%';MyISAM與InnoDB的對好比下表
對比項 MyISAM InnoDB 主外鍵 不支持 支持 事務 不支持 支持 行表鎖 表鎖,即便操做一條記錄也會鎖住整個表,不適合高併發的操做 行鎖,操做時只鎖某一行,不對其餘的行有影響,適合高併發的操做 緩存 只緩存索引不緩存真實數據 不只緩存索引還要緩存真實數據,對內存的要求比較高,並且內存的大小對性能有決定性的影響 表空間 小 大 關注點 性能 事務 默認安裝 Y Y -
性能降低SQL慢的緣由
-
查詢語句寫的爛
-
索引失效
-
單值索引
-
符合索引
-
-
關聯查詢太多join(設計缺陷)
-
服務器調優及各個參數的設置(緩衝、線程數等)
-
-
SQL執行加載的順序
-
手寫順序
select distinct
<select_list>
from
<left_table> <join_type>
join <right_tablr> on <join_condition>
where
<where_condition>
group by
<group_by_list>
having
<having_condition>
order by
<order_by_condition>
limit <limit_number> -
MySQL的執行
from <left_table>
on <join_condition> <join_type>
join <right_table>
where <where_condition>
group by <group_by_list>
having <having_condition>
select
distinct <select_list>
order by <order_by_condition>
limit <limit_number>
總結
-
2、索引及優化部分
-
索引簡介
-
是什麼
索引是幫助MySQL高效獲取數據的數據結構,本質上是數據結構(查找+排序)
-
種類
B+樹索引
hash索引
全文索引
RTree索引
-
優點
提升數據的檢索效率下降的磁盤的io
下降數據的排序成本下降了cpu的消耗
-
劣勢
實際上索引也是一張表,保存主鍵與索引字段,指向實體表的記錄,也是要佔用空間的
會下降對於insert,update,delete的速度
索引只是提升效率的一個因素
-
分類
-
單值索引:一個索引只包含一個列
-
惟一索引:索引的列必須惟一,能夠有空值
-
複合索引:一個索引包含多個列
-
基本語法
# 建立
create [unique] index indexName on table(columnname(length));
alter tablename add [unique] index indexname on (columnname(length));
# 刪除
drop index [indexname] on tablename;
# 查看
show index from tablename\G
-
-
哪些狀況適合建索引
-
主鍵自動創建惟一索引
-
頻繁做爲查詢條件的字段
-
查詢中與其餘表關聯的字段,外鍵關係創建索引
-
頻繁更新的字段不適合創建索引
-
where用不到的字段不建立索引
-
單鍵/組合索引的選擇問題(高併發下傾向於建立複合索引)
-
查詢中排序的字段排序字段經過索引訪問將大大提升訪問的速度
-
查詢中統計和分組的字段
-
-
哪些狀況不適合建索引
-
表記錄太少
-
頻繁修改的字段
-
數據重複且分佈平均的字段
-
-
性能分析
MySQL Query Optimizer 查詢優化器
負責對select語句進行優化
性能瓶頸
cpu:cpu飽和的時候通常發生在數據裝入內存或者從磁盤上讀取數據的時候
io:裝入數據元大於內存容量的時候
服務器硬件:top,free,iostat,vmstat命令查看系統的性能狀態
-
3、Explain 執行計劃
-
是什麼
使用explain關鍵字能夠模擬優化器執行sql查詢語句,從而知道,MySQL是如何處理你的sql語句的分析你的查詢語句或是表結構的性能瓶頸
-
怎麼用
explain + sql
執行計劃包含的信息
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
-
字段解釋
id
id:select查詢的序列號,包含一組數字表示查詢中執行select子句或操做表的順序
三種狀況:id相同執行順序由上至下
id不一樣若是是子查詢,id的序號會遞增,id越大優先級越高,越先被執行
id相同又不一樣會遵循上兩條規律
select_type
select_type: 查詢的類型主要是用於區別,普通查詢,聯合查詢,子查詢等複雜查詢
simple:簡單查詢不包含子查詢,或者union
primary:主查詢子查詢最外層的查詢
subquery:子查詢
derived:在from列表中包含的子查詢被標記爲dervied衍生,MySQL會遞歸執行這些子查詢,把最終結果放在臨時表裏
union:第二個select出如今union以後則被標記爲union,若union包含在from子句中,外層的select將被標記爲derived
union result:從union表中獲取結果的select
table 顯示這一行數據是關於那一張表的
type
常見的訪問類型八種
all | index | range | ref | eq_ref | const,system | null |
---|---|---|---|---|---|---|
全表掃描 | 全索引掃描比all好 | 檢索指定範圍的行 | 非惟一性索引掃描,多條記錄匹配 | 惟一性索引掃描,表中只有一條記錄匹配常見於主鍵索引惟一索引 | system表只有一行記錄 const表示經過索引一次就找到了覺得只匹配一行數據 如將主鍵置於where列表中,MySQL就能將查詢轉化爲const |
最好到最差
system > const > eq_ref > ref > range > index > all
通常來講得保證查詢至少優化到range最好到ref
prossiable_keys和key
prossiable_keys:顯示出在本次查詢中可能用到的索引,可是不必定用
keys:實際查詢的過程當中實際使用的索引爲null沒有使用索引,若查詢中使用覆蓋索引則在該索引僅出如今key列表中
key_len
索引字段的最大可能長度,並不是實際長度,再不損失精確性的狀況下越小越好
ref
顯示索引的那一列被使用了,若是可能的話儘可能是個常數
rows
找到所需的記錄讀取的行數
extra
很重要的額外信息
using filesort:使用文件內排序(壞)
using temporary:使用臨時文件(壞)
using index:使用索引(好)
using where:使用where
4、優化的幾點建議
-
全值匹配
-
最佳左前綴法則
-
不在索引列上作任何的操做(計算,函數,(自動or手動的類型轉換)),會致使索引失效而全表掃描
-
存儲引擎不能使用索引中範圍條件右邊的列
-
儘可能使用覆蓋索引只訪問索引的查詢(索引列與查詢列一致),減小select *
-
mysql在使用不等於(!= 或 <>)的時候沒法使用索引回單之全表掃描
-
is null ,is not null 也沒法使用索引
-
like以通配符開頭會致使索引失效全表掃描
-
字符串不單引號索引失效
-
少用or用來鏈接時會使索引失效
-
永遠小表驅動大表
-
group by/order by排序字段也會用到索引(左前綴,儘可能使用where)
5、查詢截取分析
-
慢查詢日誌截取慢sql
# 查看
show variables like '%slow_query_log%';
# 開啓
set global slow_query_log=1
# 查看記錄sql的閾值時間
show variables like 'long_query_time%';
# 設置閾值時間
set global long_query_time=3; -
show profile
# 查看是否支持
show variables like 'profiling'
# 開啓
set profiling=on
# 查看結果
show profiles;
show profile cpu,block io from query [問題sql的query_id];
6、MySQL鎖機制
-
概念
鎖是計算機協調鎖個進程或者線程併發訪問某一資源的機制
-
分類
讀鎖/寫鎖
-
讀鎖:共享鎖
-
寫鎖:排它鎖
表鎖/行鎖
-
表鎖:鎖整張表(偏讀,偏向MyISAM存儲引擎,開銷小,加鎖快,無死鎖,鎖定的粒度大,大,發生鎖衝突的機率高,併發度低)
-
行鎖:鎖一行(偏寫,偏向InnoDB存儲引擎,開銷大,加鎖慢會出現死鎖,鎖定的粒度小,發生鎖衝突的機率最低,併發度也高)
-
事務及ACID屬性
事務是由一組SQL語句組成的邏輯處理單元,事物具備如下四個屬性
-
原子性(Atomicity):事務是一個原子性的操做單元,其對數據的修改,要麼全都執行,要麼全都不執行
-
一致性(Consistent):在事務開始和完成時,數據都必須保持一致的狀態,這意味着,全部相關的數據規則都必須應用於事務的修改,以保持數據的完整性,十五屆數值,全部的內部數據(如b樹索引或雙向鏈表)也都必須是正確的
-
隔離性(Isolation):數據庫系統提供必定的隔離機制,保證十五在不收外部併發操做的影響的「獨立」環境執行,這意味着事務處理過程當中的中間狀態對外部是不可見的,反之亦然
-
持久性(Durable):事務完成以後,它對數據的修改是永久性的,即便出現系統故障也可以保持
併發處理帶來的問題
-
更新丟失:相似於版本覆蓋
-
髒讀:讀到已修改還沒有提交的數據
-
不可重複讀:兩次讀的不同
-
幻讀:事務a讀到了事務b提交新增的數據不符合隔離性
數據庫的事務隔離級別
數據庫的隔離級別 數據一致性 髒讀 不可重複讀 幻讀 讀未提交 最低級別,只能保證不讀物理損壞的數據 Y Y Y 讀已提交 語句級 N Y Y 可重複讀 事務級 N N Y 可序列化 最高級別,事務級 N N N # 查看數據庫的隔離級別 MySQL默認爲可重複讀
show variables like 'tx_isolation';
# 鎖定一行
begin;
sql+for update;
commit; -
# 建表
create table mylock(
id int not null primary key auto_increment,
name varchar(20)
) engine myisam;
# 插入數據
insert into mylock(name) values('a'),('b'),('c'),('d'),('e');
select * from mylock;
# 手動增長表鎖
lock table 表名1 read,表名2 write;
# 查看錶的加鎖狀態
show open tables;
# 解鎖
unlock tables; -