鏈接層:鏈接與線程處理,這一層並非MySQL獨有,通常的基於C/S架構的都有相似組件,好比鏈接處理、受權認證、安全等。mysql
服務層:包括緩存查詢、解析器、優化器,這一部分是MySQL核心功能,包括解析、優化SQL語句,查詢緩存目錄,內置函數(日期、時間、加密等函數)的實現。算法
引擎層:負責數據存儲,存儲引擎的不一樣,存儲方式、數據格式、提取方式等都不相同,這一部分也是很大影響數據存儲與提取的性能的;對存儲層的抽象。sql
存儲層:存儲數據,文件系統。數據庫
二 , 存儲引擎緩存
查看數據庫支持的存儲引擎:show engines;安全
若是要想查看數據庫默認使用哪一個引擎,能夠經過使用命令: show variables like '%storage_engine%';架構
指定數據庫對象的引擎:併發
create table tb( id int(4) auto_increment , name varchar(5), dept varchar(5) , primary key(id) )ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ;
查看建表語句:show create table default_table;數據庫設計
雖然 MySQL 裏的存儲引擎不僅是 MyISAM 與 InnoDB 這兩個,但經常使用的就是它倆了。可能有站長並未注意過 MySQL 的存儲引擎,其實存儲引擎也是數據庫設計裏的一大重要點,那麼博客系統應該使用哪一種存儲引擎呢?函數
下面咱們分別來看兩種存儲引擎的區別。
經過以上九點區別,結合我的博客的特色,推薦我的博客系統使用MyISAM,由於在博客裏主要操做是讀取和寫入,不多有鏈式操做。因此選擇MyISAM引擎使你博客打開也頁面的效率要高於InnoDB引擎的博客,固然只是我的的建議,大多數博客仍是根據實際狀況下謹慎選擇。
三, sql優化
3.1.1 mysql 內部實現索引原理(B+Tree)
3.1.1.1 , 二叉樹
3.1.1.2 , B-Tree
B-Tree中的每一個節點根據實際狀況能夠包含大量的關鍵字信息和分支,以下圖所示爲一個3階的B-Tree:
每一個節點佔用一個盤塊的磁盤空間,一個節點上有兩個升序排序的關鍵字和三個指向子樹根節點的指針,指針存儲的是子節點所在磁盤塊的地址。兩個關鍵詞劃分紅的三個範圍域對應三個指針指向的子樹的數據的範圍域。以根節點爲例,關鍵字爲17和35,P1指針指向的子樹的數據範圍爲小於17,P2指針指向的子樹的數據範圍爲17~35,P3指針指向的子樹的數據範圍爲大於35。
模擬查找關鍵字29的過程:
分析上面過程,發現須要3次磁盤I/O操做,和3次內存查找操做。因爲內存中的關鍵字是一個有序表結構,能夠利用二分法查找提升效率。而3次磁盤I/O操做是影響整個B-Tree查找效率的決定因素。
B-Tree相對於AVLTree縮減了節點個數,使每次磁盤I/O取到內存的數據都發揮了做用,從而提升了查詢效率。
3.1.1.3 , B+Tree(查詢任意數據的次數是 n)
B+Tree是在B-Tree基礎上的一種優化,使其更適合實現外存儲索引結構,InnoDB存儲引擎就是用B+Tree實現其索引結構。
從上一節中的B-Tree結構圖中能夠看到每一個節點中不只包含數據的key值,還有data值。而每個頁的存儲空間是有限的,若是data數據較大時將會致使每一個節點(即一個頁)能存儲的key的數量很小,當存儲的數據量很大時一樣會致使B-Tree的深度較大,增大查詢時的磁盤I/O次數,進而影響查詢效率。在B+Tree中,全部數據記錄節點都是按照鍵值大小順序存放在同一層的葉子節點上,而非葉子節點上只存儲key值信息,這樣能夠大大加大每一個節點存儲的key值數量,下降B+Tree的高度。
B+Tree相對於B-Tree有幾點不一樣:
將上一節中的B-Tree優化,因爲B+Tree的非葉子節點只存儲鍵值信息,假設每一個磁盤塊能存儲4個鍵值及指針信息,則變成B+Tree後其結構以下圖所示:
一般在B+Tree上有兩個頭指針,一個指向根節點,另外一個指向關鍵字最小的葉子節點,並且全部葉子節點(即數據節點)之間是一種鏈式環結構。所以能夠對B+Tree進行兩種查找運算:一種是對於主鍵的範圍查找和分頁查找,另外一種是從根節點開始,進行隨機查找。
上面都應該知道B+Tree 了吧,因此咱們在創建索引時,會生成一個B+Tree 若是咱們在只查詢索引字段時,sql 語句就直接去B+Tree 查,不會再去數據表中查了,這樣提高性能是很重要的。 還有就是對於老是修改的字段不要對他創建索引,由於字段修改了,B+Tree 結構就要重構,這要是會下降性能的。
3.1.1 索引分類:
mysql索引的四種類型:主鍵索引
、惟一索引
、普通索引
和全文索引
。經過給字段添加索引
能夠提升數據的讀取速度
,提升項目的併發能力和抗壓能力。索引優化
時mysql中的一種優化方式。索引的做用至關於圖書的目錄
,能夠根據目錄中的頁碼快速找到所需的內容
。
主鍵索引: 主鍵是一種惟一性索引,但它必須指定爲PRIMARY KEY
,每一個表只能有一個主鍵。
alert table tablename add primary key (`字段名`)
惟一索引: 索引列的全部值都只能出現一次,即必須惟一
,值能夠爲空
。
alter table table_name add primary key (`字段名`);
普通索引 : 基本
的索引類型,值能夠爲空,沒有惟一性的限制。
alter table table_name add index (`字段名`);
全文索引:
全文索引的索引類型爲FULLTEXT
。全文索引能夠在varchar、char、text
類型的列上建立。能夠經過ALTER TABLE
或CREATE INDEX命令建立。對於大規模的數據集,經過ALTER TABLE(或者CREATE INDEX)命令建立全文索引要比把記錄插入帶有全文索引的空表更快。MyISAM
支持全文索引,InnoDB
在mysql5.6以後支持了全文索引
。 全文索引不支持中文
須要借sphinx(coreseek)
或迅搜<、code>技術處理中文。
3.2.2 索引的機制
1.爲何咱們添加完索引
後查詢速度爲變快
?
傳統的查詢方法,是按照表的順序遍歷的,不論查詢幾條數據,mysql須要將表的數據從頭至尾遍歷一遍
在咱們添加完索引以後,mysql通常經過BTREE算法
生成一個索引文件
,在查詢數據庫時,找到索引文件進行遍歷(折半查找大幅查詢效率)
,找到相應的鍵從而獲取數據佔用磁盤空間
二叉樹類型的文件
,可想而知咱們的dml操做一樣也會對索引文件進行修改,因此性能會降低更新很是頻繁的字段
不適合做爲索引
不會出如今where子句中
的字段不應建立索引
常用
b: 該字段的內容不是惟一的幾個值
c: 字段內容不是頻繁變化
。
3.2.二、SQL解析順序
SELECT DISTINCT ..... FROM ..... JOIN ..... ON ..... WHERE..... GROUP BY ..... HAVING ..... ORDER BY ..... LIMIT .....
然而它的執行順序是這樣的
FROM ..... ON ..... JOIN ..... WHERE ..... GROUP BY ..... HAVING ..... SELECT DISTINCT ..... ORDER BY ..... LIMIT .....
通常說來,索引應創建在那些將用於JOIN,WHERE判斷和ORDERBY排序的字段上。儘可能不要對數據庫中某個含有大量重複的值的字段創建索引。對於一個ENUM類型的字段來講,出現大量重複值是頗有可能的狀況.
3.2.4 使用索引時,有一些技巧:
1.索引不會包含有NULL的列
只要列中包含有NULL值,都將不會被包含在索引中,複合索引中只要有一列含有NULL值,那麼這一列對於此符合索引就是無效的。
2. 索引要創建在常常進行select操做的字段上。而常常修改的字段,沒不必創建索引了,由於,你創建了索引會生成一個B+樹,你修改了該索引的字段後,這個B+樹就須要修改,反而對性能不是很好。
3. 複合索引 : 複合索引,不要跨列或無序使用(最佳左前綴)
4.like語句操做: 通常狀況下不鼓勵使用like操做,若是非使用不可,注意正確的使用方式。like ‘%aaa%’不會使用索引,而like ‘aaa%’可使用索引。
5. 不要在索引上進行任何操做(計算、函數、類型轉換),不然索引失效
6.不使用NOT IN 、<>、!=操做,但<,<=,=,>,>=,BETWEEN,IN是能夠用到索引的
7.索引要創建在常常進行select操做的字段上。
這是由於,若是這些列不多用到,那麼有無索引並不能明顯改變查詢速度。相反,因爲增長了索引,反而下降了系統的維護速度和增大了空間需求。
8.索引要創建在值比較惟一的字段上。
9.對於那些定義爲text、image和bit數據類型的列不該該增長索引。由於這些列的數據量要麼至關大,要麼取值不多。
10.在join操做中(須要從多個數據表提取數據時),mysql只有在主鍵和外鍵的數據類型相同時才能使用索引,不然及時創建了索引也不會使用。
三, sql性能問題
a.分析SQL的執行計劃 : explain ,能夠模擬SQL優化器執行SQL語句,從而讓開發人員 知道本身編寫的SQL情況
b.MySQL查詢優化其會干擾咱們的優化(mysql服務層有一個sql優化器),能夠對咱們寫的sql進行優化,這是咱們控制不了的。
查詢執行計劃: explain +SQL語句 explain SELECT * from book ;
id : 編號
select_type :查詢類型
table :表
type :索引類型 system>const>eq_ref>ref>range>index>all ,要對type進行優化的前提:有索引 通常能達到range 就行。
possible_keys :預測用到的索引
key :實際使用的索引
key_len :實際使用索引的長度
ref :表之間的引用
rows :經過索引查詢到的數據量
Extra :額外的信息 下面是他可能發出的狀況
i). using filesort : 性能消耗大;須要「額外」的一次排序(查詢) 。常見於 order by 語句中。 解決:where哪些字段,就order by那些字段2
ii). using temporary:性能損耗大 ,用到了臨時表。通常出如今group by 語句中。 解決: 避免:查詢那些列,就根據那些列 group by .
iii). using index :性能提高; 索引覆蓋(覆蓋索引)。緣由:不讀取原文件,只從索引文件中獲取數據 (不須要回表查詢)
只要使用到的列 所有都在索引中,就是索引覆蓋using index
iii).using where (須要回表查詢)。
假設age是索引列 但查詢語句select age,name from ...where age =...,此語句中必須回原表查Name,所以會顯示using where. 解決 吧name 也添加到索引中去。