mysql邏輯架構
![圖片描述 圖片描述](http://static.javashuo.com/static/loading.gif)
鏈接層
最上層是一些客戶端和鏈接服務,包含本地scoket同窗和大多數基於客戶端/服務端工具實現的相似於tcp/ip的通訊,主要完成一些相似鏈接處理,受權認證,及相關的安全方案,在該層引入線程池的概念,爲經過認證安全接入的客戶端提供線程,一樣在該層上能夠實現基於SSL的安全連接,服務器也會爲安全接入的每一個客戶端驗證它所具有的操做權限。
服務層
第二層架構主要完成大多數的核心服務功能,如SQL接口,並完成緩存查詢,SQL的分析和優化及部份內置函數的執行,全部跨存儲引擎的功能也在這一層實現,如過程,函數等,在該層,服務層會解析查詢並建立相應的內部解析樹,並對其完成響應的優化確認查詢表的順序,是否利用索引等,最後生成相應的執行操做,若是是select語句,服務器還會查詢內部的緩存,若是緩存空間足夠大,這樣就解決大量讀操做的環境中可以很好的提供系統性能。
存儲引擎層
存儲引擎層,存儲引擎真正負責了MySQL中數據的存儲和提取,服務器經過API與存儲引擎進行通訊,不一樣的存儲引擎具備的功能不一樣,這樣咱們能夠根據本身的實際須要進行選取,例如:MYISAM和InnoDB。
數據存儲層
主要將數據存儲在運行於裸設備的文件系統之上,並完成存儲引擎的交互(文件系統)。
MyISAM和InnoDB對比
功能點 |
MyISAM |
InnoDB |
主外鍵 |
不支持 |
支持 |
事務 |
不支持 |
支持 |
行表鎖 |
表鎖,操做一條記錄也會鎖住整個表,不支持高併發 |
行鎖,操做一條記錄只會鎖住一行,適合高併發 |
緩存 |
只緩存索引,不緩存數據 |
緩存索引也緩存數據,對內存要求高,內存大小直接影響性能 |
表空間 |
小 |
大 |
關注點 |
性能 |
事務 |
默認安裝 |
是 |
是 |
sql慢的緣由
- 查詢語句效率低
- 索引失效或者沒建索引
- join太多
- 服務器參數設置
索引
什麼是索引
索引是一種數據結構,提升查詢的效率
索引會將數據排序,從而可以快速查找
數據庫除了有數據之外,還維護着一個知足特定查找算法的數據結構,這種數據結構以某種方式指向數據,這樣就能夠利用這種數據結構高效地查找數據,這種數據結構就是索引。
索引的優勢
- 提升查詢效率,下降IO成本
- 對列進行排序,下降排序成本
索引的缺點
- 索引也是一張表,保存了鍵值對,並指向實際數據,索引列也須要佔用空間。
- 雖然索引可以提高查詢的效率,可是會下降更新的效率,好比insert,update,delete,由於更新表時,mysql不只要保存新的數據,還要更新索引列的信息。
索引分類
- 單值索引
- 惟一索引
- 複合索引
哪些狀況能夠建索引
- 主鍵自動創建惟一索引
- 頻繁做爲查詢條件的字段要創建索引
- 與其餘表關聯的字段,外鍵字段創建索引
- 查詢中的排序字段
- 查詢中統計或分組的字段
哪些狀況不要建索引
- 表數據不多(300萬一下的)
- 常常增刪改的字段
- 數據重複且平均的字段,這種字段建索引沒有意義
explain
explain能夠模擬優化器執行sql語句,從而能夠了解sql語句執行的內部原理,以此來分析性能瓶頸。
使用方法
mysql> explain sql_sentence;
做用
- 表的讀取順序
- 數據庫讀取的操做類型
- 哪些索引能夠被使用
- 哪些索引實際被使用
- 表之間的引用
- 每張表有多少行被優化器查詢
輸出信息
id
表的讀取順序
- id相同:自上而下執行語句
- id不一樣:id越大,優先級越高,越先執行
- id有相同的也有不一樣的:先執行id最大的第一個,而後平級的順序執行,再執行小一級id的語句
select_type
查詢的類型
- simple:簡單的select查詢,查詢中不含子查詢或union
- primary:查詢中包含任何複雜的子查詢,則最外層的查詢是此類型
- subquery:查詢中包含子查詢
- derived:臨時衍生表
- union:第二個select出如今union以後
- union result:union以後的結果
table
數據對應的表
type
顯示查詢使用了哪一種類型
- system:表中只有一行數據,是const類型的特例
- const:經過索引一次就找到了,經過主鍵或惟一索引與常量值比較只匹配一行數據,用於單表查詢
- eq_ref:惟一性索引掃描,對於每一個索引鍵,表中只有一條記錄與之匹配,用於多表聯查
- ref:非惟一索引掃描,返回全部匹配的行
- range:檢索給定範圍的行,好比where中的in、between、>、<
- index:只遍歷索引樹,用於獲取表的全部索引字段的數據,select id from table;
- all:全表掃描,從磁盤中讀取數據,百萬級數據查詢出現all則須要優化
possible_key
顯示可能用到的索引值,但不必定會被實際用到
key
實際使用到的索引,若是爲空則沒有使用或者根本沒有索引
key_len
索引中使用的字節數,長度越短越好
它表示索引字段的最大可能長度,而不是實際長度
ref
顯示那一列索引被用到了,多是const或者某一列
rows
大體估算找到所需信息須要讀取的行數
extra
額外信息
- using filesort:mysql對數據進行從新的排序,沒法利用索引進行的排序叫文件排序
- using temporary:排序時建立了臨時表
- using index:查詢時不須要回表查詢,直接經過索引就能夠獲取查詢的數據,若是出現了using where表示索引列被用來查找特定行,若是沒出現則說明索引列只用來提取數據
索引優化
防止索引失效
- 最佳左前綴法則:若是索引了多個列,查詢須要從索引的最前列開始,且不能跳過索引中的列
- 不要在索引列上作任何操做,好比各類函數操做,否則會致使索引失效並轉向全表掃描
- 在where中使用了範圍,則範圍右邊的列失效
- 儘可能使用覆蓋索引(索引列和查詢列順序一致),少用select *
- 在使用不等於(!=或者<>)時,沒法使用索引,使用的是全表掃描
- is null和is not null沒法使用索引
- like以通配符開頭的(like '%xyz'),索引會失效,變成全表掃描
- 隱式類型轉換會致使索引失效
- 少用or
慢查詢
在/var/lib/mysql有log文件 使用mysqldumpslow查看日誌