MySql存儲引擎+表解壓縮機制+索引+查詢緩存機制+慢查詢日誌

.大型網站優化之MySql優化

1.優化和不優化的對比的

在業界當中咱們有一個叫大數據(big data)的概念,所謂的大數據指代千萬級別以上的數據做爲起步的數據。因此咱們如今須要對兩張都具備50331650條記錄的表進行查詢對比,其中表名爲tbl_no的表是沒有作過任何優化手段的表,表名爲tbl_yes的表是作過優化手段的表。這個實驗的目的是觀察具備優化手段和不具備優化手段的查詢中速度的差異。php

實驗條件:mysql

1)兩張表的數據記錄總數是相同的面試

2)兩張表的數據字段結構也是同樣的redis

3)查詢的記錄的where條件都是username='itcast'的用戶算法

實驗結果對比出現以下的結果:sql

①表tbl_no查詢條件爲username='itcast'的用戶耗時時間爲15.59sec:shell

 

 

②表tbl_yes查詢條件爲username='itcast'的用戶耗時時間爲:0.01秒數據庫

 

 

最終的對比結果以下:編程

 

 

2.業界中對「慢」的定義[八秒原則]

在今天互聯網當中有一個所謂的8秒原則,根據統計一個用戶在8秒中以內若是不能打開一個網站,那麼有99%的用戶會選擇關閉瀏覽器。vim

其實8秒原則是相對論,由於若是一個網站打開的速度超過兩秒達到3秒鐘才能打開其實就已經無限在挑戰用戶的耐心了,也就說其實咱們作優化是儘量控制速度在2秒內完成,這樣才能更好的留住用戶,避免挑戰用戶的等待耐心.

 

 

然而咱們說爲何數據庫的查詢速度慢就會影響用戶等待的耐心呢?

3.PHP+MySql架構的請求原理

在開發的當中咱們使用php+mysql的架構佔據了主要的開發方式,這種架構造成的請求其實真正的結果執行最終發生在MySql數據庫當中,其主要流程圖以下所示:

 

 

若是這個請求的過程中,數據庫響應達到了?秒,那麼也就就是說瀏覽器的客戶在不斷等待網站數據返回(打開),也就是這樣8秒原則的定律就會成型,用戶關閉瀏覽器的可能性是99%的.

.MySql優化的層面

1.表設計層面:存儲引擎,索引,列類型,範式規範(冗餘)

2.服務器層面:實現數據庫主從複製(讀寫分離)

3.編程層面:避免在循環中select數據表

4.緩存層面:使用nosql技術

5.系統層面:使用Linux操做系統做爲服務器底層

6.其餘方面:硬件,集羣服務器,靠譜的idc供應商,靠譜的技術團隊

天下沒有免費的午飯,任何的優化其實都具備主觀的性質存在並且每一種優化的手段基本上都須要付出必定的代價。世界上沒有一個很是標準的優化技術給你做爲參考,優化是一門永遠不會中止課題,隨着你的經驗的積累,那麼你的優化手段和看法就有可能不一樣

.MySql存儲引擎

1.什麼是存儲引擎

MySQL中的數據是經過各類不一樣的技術格式存儲在文件(或者內存)中的。技術和自己的特性就稱爲"存儲引擎"。每一種需求都使用不一樣的存儲引擎,才能獲取不一樣的數據庫性能和功能上的需求。

若是在生活把獨門獨戶的樓房(縱向結構)和平房(平面結構)看做存儲引擎的話,不一樣的建築結構對於不一樣的需求來講就有不一樣的便利。對於送快遞的人來講,獨門獨戶的樓房便於快遞的小哥的投遞。對於裝空調或者搬傢俱的師傅來講,平房天然更有利於空調的安裝和傢俱的進出。

由此咱們能夠知道一個結論,選擇不一樣的存儲引擎就是選擇不一樣的技術格式(結構),他們的特性決定他們對某種需求的優點,所以存儲引擎的正確選擇是作MySql優化的關鍵。

2.存儲引擎的查看和默認項

mysql數據庫當中其實有5種存儲引擎,而且會默認地幫用戶選定其中一個,不一樣的數據庫版本默認的選項是不同的,因此咱們能夠經過如下的命令去了解當前mysql的存儲引擎相關狀況:

語法規則: show engines

執行命令效果以下:

 

 

(針對5.1.73的版本)

經常使用的存儲引擎通常是MyISAM和Innodb,MyIsam是默認的存儲引擎

Memory其實之前也是一個很受歡迎的引擎,然而它如今已經被Memcache和redis取代它的地位了,所以使用的人就極少了,這個引擎是一個內存機制的引擎相似Memcache,但性能不如memcache強大.(瞭解)

3.MyISAM表的文件及其特色

mysql中,mysql把全部的數據庫用目錄來表示,把數據用文件的方式來進行存儲。

mysql數據庫在Linux當中它的目錄路徑在:/var/lib/mysql

創建一個名爲demo的數據庫

代碼參看:code/demo.sql

 

 

查詢/var/lib/mysql就會發覺多了一個名爲demo的目錄

 

 

查看demo數據庫中的myisam引擎下的表文件

 

 

/var/lib/mysql/demo目錄下,產生如下文件:

 

 

mysql當中myisam引擎存儲數據有3個文件組成

.frm文件用於存儲建表的結構信息(字段信息)

.MYD用於儲存表的記錄信息

.MYI用於儲存表的索引信息(例如:主鍵)

MyISAM存儲引擎的特色:

建表結構,表記錄信息和索引信息都獨立存在的,因爲MyISAM存儲引擎的技術特色是結構和數據分離,所以能夠更好地觀察到該存儲引擎的文件變化狀況,所以大部分狀況下咱們作優化都是使用MyISAM引擎。

實驗:建立一張產品表goods,代碼以下:

代碼詳細請參考:code/goods.sql

 

 

建表完成後,發覺/var/lib/mysql/demo下的文件有以下變化:

 

 

 

用複製數據的方法添加記錄查看myisam引擎表的變化

1步:向goods表添加3條記錄

 

 

2步:以倍增的方式複製數據

 

 

反覆執行的結果以下:

 

 

你會很快就能夠插入幾十萬甚至幾千萬條數據

3步:查看結果發現其實文件的大小變化以下圖所示:

 

 

myisam引擎的表,當數據發生變化的時候,只有.MYI文件和.MYD文件會發生變化,而.frm文件不會發生改變

4.Innodb存儲引擎表的文件及其特色

mysql中,mysql把全部的數據庫用目錄來表示,把數據用文件的方式來進行存儲。

mysql數據庫在Linux當中它的路徑在:/var/lib/mysql,所以不管是Innodb的引擎仍是MyISAM引擎的表數據都存在於該目錄當中,因此一樣地咱們能夠在這個目錄中進行Innodb引擎的表文件變化。

 

代碼詳細請參考:code/pros.sql

實驗:建立一張產品表pros,代碼以下:

 

 

觀察其實文件的變化以下:

 

 

問題來了:查看以上結果後你會發覺在Innodb只有一個.frm文件用於存儲數據表的結構,那麼Innodb的記錄信息和索引文件存放哪裏呢?

插數據來觀察innodb的變化

1步:向pros表添加3條記錄

 

 

2步:以倍增的方式複製數據

 

 

3步:觀察結果,能夠得出如下結論:

 

 

被數據發覺/var/lib/msyql/demo目錄沒有任何的改變

 

 

然而咱們會發現若是咱們繼續倍增數據在/var/lib/mysql有一個文件ibdata1會發生改變,效果以下:

 

 

很快咱們發覺會有一個這樣的文件產生ibdata1,隨着你對innodb的數據表pros添加數據,這個文件的大小發生了變化,由於innodb是把全部表記錄信息和索引信息都共享在一個文件當中的。若是咱們有10張innodb的表那麼咱們10張表的記錄信息和索引信息都會存放到這個文件當中,所以咱們要針對某一張innodb的表來作優化是很難的。因此咱們證實了一點,作優化通常是針對myisam的表。

Innodb存儲引擎的特色:結構和數據共享,目的是爲了保證數據的完整性,爲追求數據完整性和安全性而生的存儲引擎。

5.MyISAMInnodb的區別和應用場景(面試題)

Innodb

專一在數據完整性和安全性方面,例如:事務等,對查詢,插入數據的效率支持就比較差

Myisam

MyIsam的是追求性能的而生的。所以咱們說的mysql優化其實不少時候就是針對myisam引擎而言,但優化是要付出代價的,你要優化就要犧牲掉某些東西,若是你當前的業務要求安全性很高那麼你就別談什麼優化了,也不能選擇myisam了。

兩種存儲引擎的應用場景(引擎的選擇)

大量查詢(select)或者寫入(update,insert,delete)就選擇Myisam,例如:博客系統,論壇等

數據涉及利益和金錢交易,就須要很嚴謹和具備安全性,例如銷售、財務,股票等系統,就選擇innodb

 

 

.MyISAM的表解壓縮機制

1.應用場景

37遊戲公司當中有一個這樣的業務,他們的遊戲是按地區訪問的,例如:你是廣州的玩家,通常訪問的是廣州這邊的遊戲服務器數據,若是是你是上海的玩家那麼你訪問的遊戲服務器數據通常是上海的,有時候總部某些遊戲有更新(好比:更新的了遊戲的地圖),這時須要把這些遊戲的更新數據進行其餘地區的同步,好比同步到上海,這時就須要進行數據的遷移和複製.其原理圖以下所示:

 

 

 

 

這時會產生一個這樣的問題:如何提升數據遷移和複製的速度?

2.使用MyISAM的表壓縮機制

壓縮機制的優化實際上是爲了節約硬盤空間和傳輸文件的,對select語句的優化的最多提高可以達到0.1-0.8秒,所以解壓縮機制的優化實際上並非提升select語句的手段。

MyISAM的表壓縮詳細步驟以下:

1步:找到您須要壓縮表文件,好比說若是但願壓縮test數據庫當中tbl_yes這張表,那麼我就應該切換到/var/lib/mysql/test目錄,找到tbl_yes這張表文件以下:

 

 

確認在沒有進行壓縮優化以前的

tbl_yes.frm的大小是8.4k

tbl_yes.MYD的大小是961M

tbl_yes.MYI的大小是684M

壓縮其實跟您當前計算機cpu和硬盤的性能有關係,若是你硬盤讀寫能力很強,cpu的核數很高,那麼壓縮的速度就很快,反之壓縮的速度就比較,壓縮數據實際上是有一個比率值的,若是用家庭電腦進行數據壓縮,每一個電腦壓縮的比率值是不一樣,通常若是能壓縮50%的比率就已經很厲害了,固然真正的服務設備通常壓縮的比率高達80%以上,使用myisam的表壓縮實際上是一個很是傷硬盤的過程,因此真正的服務器常常要備份不少的讀寫硬盤進行更換,成本是很是高的.

2步:使用命令myisampack命令進行壓縮,命令的格式和機制以下,壓縮必須壓縮MYI索引文件,而不能直接壓縮MYD文件,語法格式以下:

myisampack [數據表的索引文件全名]

執行以下:

 

 

執行壓縮必須在/var/lib/mysql/test目錄下進行,回車就會進行壓縮優化,時間有長有短,根據設備而定,出現如下界面表明正在進行壓縮優化:

 

 

若是壓縮完成後就會出現如下界面:

 

 

3步:壓縮完成,咱們觀察壓縮的結果以下所示:

 

 

咱們發覺tbl_yes.MYI文件被咱們壓縮壞了,由於它有原來的684M變成了1k,所以該文沒法使用,所以數據也沒法正常的讀取了,所以出現這個問題,咱們就須要重建索引文件,凡是通過壓縮優化100%的可能性都是壓壞索引文件,觀察壓縮的結果咱們發覺其實mysql官方提示咱們一句這樣的話,記得執行myisamchk -rq

 

 

4步:執行myisamchk -rq重建tbl_yes表的索引爲文件tbl_yes.MYI

其語法格式以下:

myisamchk -rq [要重建的索引文件名稱]

執行命令以下所示:

 

 

重建因此完成會從新恢復到shell標誌當中,以下圖所示:

 

 

重建索引以後,其實會發覺索引文件其實依然是有損壞的,由於mysql的開發者爲了保證MYD文件的數據完整性,因此對索引文件進行性能的犧牲,其實壓縮以後數據庫表只能是隻讀的,不能插入任何的數據這個就是壓縮的缺點,可是壓縮不須要擔憂數據丟失和完整性,由於mysql5.1.73對Myisam壓縮進行很是嚴謹的測試.重建索引的過程好像有點死機的感受,可是不須要過度擔憂,由於這屬於正常繼續耐心等待.

 

 

MYD文件被壓縮稱爲了324M,比原來的961M大大的縮減,所以提升網絡傳輸的速度.

壓縮優化完成必須刷新表

5步:數據庫的索引文件重建以後,並不表明立刻就可使用,由於這時其實索引文件重建後,沒法正常讀取壓縮後數據,可是咱們可使用刷新表的技術,來讓數據庫恢復讀取功能,語法以下:

mysqladmin -uroot -p登陸密碼 flush-table #刷新mysql當中表

mysqladmin -uroot -p123456 flush-table

 

 

執行沒有返回任何的錯誤,那麼就表明刷新表成功

5步:登陸數據庫當中,從新查詢tbl_yes這種表,結果以下:

 

 

發覺壓縮優化,數據不會丟失,因而接着查詢username=itcast的用戶

 

 

能夠正常的查出信息,而且性能上沒有受到任何的影響,固然也沒有任何的提升,接下來插入一條數據,出現結果以下:

 

 

發覺壓縮優化代價就是致使壓縮後表是隻讀的狀態,若是咱們須要繼續對tbl_yes這種表進行數據的插入,那麼咱們應該怎麼辦呢?答案:解壓當前表

注意一個問題:在壓縮優化層面,有一句俗語叫作解鈴還須繫鈴人,也就說誰進行壓縮誰就負責解壓,爲何呢?由於數據其實在現實開發當中通常是由總部進行規劃和統一的,分部不能隨意插入數據,分部只能讀取總部插入的數據,所以壓縮優化就被運用在37wan這個場景

 

3.使用MyISAM的解壓機制

若是一張表進行了壓縮,那麼這張表就只能是隻讀的,若是須要該表可以從新進行寫入的操做,那麼就必須使用MyISAM的解壓機制.

MyISAM的表解壓的詳細步驟以下:

1步:一樣須要找到要進行解壓的表,而後使用命令: myisamchk --unpack

進行解壓操做,若是你忘記了這個命令,咱們可使用man myisamchk來進行查看

發覺有一個這樣的選項:

 

 

2步:使用命令以下:

myisamchk --unpack [索引文件名稱],執行效果以下:

 

 

解壓完成後,會出現如下界面:

 

 

文件解壓後的變化以下:

 

 

其實解壓也沒法恢復到沒有壓縮的數據狀態,文件依然有所損壞的,包括MYD文件也是有所損壞的但不影響任何的操做

3步(建議步驟):解壓完成後,一樣不要立刻進行數據的插入,由於若是這時進行數據的插入,可能會爲表的後續發展產生一些bug,建議也是解壓後進行刷新恢復以後再進行插入.其實這一步不是必須的.執行命令:mysqladmin -uroot -p123456 flush-table

 

 

刷新以後,必需要退出mysql的登陸而後再從新登陸

4步:登陸mysql數據進行數據插入和查詢操做,結果以下:

 

 

.MySqlexplain執行計劃

1.什麼是執行計劃

explain是一個Mysql性能顯示的工具,它顯示了MySQL如何使用索引來處理select語句以及鏈接表。能夠幫助選擇更好的索引和寫出更優化的查詢語句。在開發當中咱們通常用explain來查看索引的使用狀況,explain你能夠把它理解成爲一個查看索引使用狀況的工具,但官方對它的定義是explain是一個mysql執行計劃(ex=execute),不過這種概念的東西不須要過度的糾結,反正你知道有這麼一回事就能夠了。

語法規則:explain [select 語句]

執行explain select * from  tbl_no where username='itcast' 結果以下:

 

 

explain執行計劃最重要的選項:

 

 

 

2.explain執行計劃分析tbl_yes

 

 

 

比對explain掃描tbl_yes和tbl_no的結果你會發現其實只要使用索引,那麼速度就會很快,並且只要 使用到索引那麼就必定不會是全表掃描all的方式,而且掃描的記錄行數也大大縮減,所以這個就是爲何tbl_yes比tbl_no快的主要緣由,關鍵一點就是tbl_yes有使用到索引.

.索引的概述

1.爲何要使用索引

數據庫的索引其實就好像書本的目錄同樣,假設你拿一本新華字典來查一個字,若是新華字典的拼音字母的目錄不見了,筆畫部首的目錄被撕掉了,這時你去找這個字你就慢了。但若是從新把這個目錄給你,你的查找這個字的速度確定快了不少。索引就至關於這個目錄的做用,它能提升select語句查找記錄的速度。

 

 

Mysql當中儘管索引查找的速度很是快,然而Mysql的任何一種優化都是須要付出必定代價的,添加索引會佔據不少的磁盤的空間,也會下降寫操做(delete , update , insert)語句的效率。其實索引咱們很早就接觸過,主鍵就是一種索引。主鍵也是全部索引當中最高效率的。

 

 

在數據庫當中,索引優化有一個原則:使用上索引就必定會快,而且使用上索引就不會是ALL

2.常見索引的分類

Mysql的經常使用引擎Innodb和MyISAM當中它們的索引結構是一種叫Btree的類型,由於它們是根據一種叫「二叉樹」的算法建立出來的。在Mysql當中常見的索引使用有4種,分別爲:

主鍵索引( Primary Key )

普通索引( Key )

惟一性索引(Unique)

全文索引(FullText):這個索引其實被sphinx取代了其地位

特殊的索引有1種:前綴索引

3.查看索引的方法

1.語法規則:show index from [表名稱]

使用命令: show index from tbl_yes

 

 

primary是一個主鍵索引,它做用在id字段中

uname的普通索引,它做用在username字段中

2.語法規則:show create table from [表名稱]

使用命令:show create table tbl_yes

 

 

以上方法實際上是經過查看建表的結構來查看索引的相關信息

.主鍵索引

主鍵索引的原則和場景:

在開發當中咱們每每須要對一些重複性的數據進行區分,那麼這時咱們就須要使用主鍵索引,主鍵索引既不能爲null,也不能重複,更不能爲空字符串。在id字段中出現最多,一般還會配合自增加一塊兒使用,主鍵索引也是全部索引當中查詢速度最快的索引。

1.在建立表的時候建立主鍵索引

代碼詳細請參考:code/pk1.sql

語法規則:primary key關鍵字

 

 

插入一些數據測試主鍵:

 

 

使用explain執行計劃查看主鍵是否會被使用上:

使用命令explain select * from pk1 where id=2;和explain select * from pk1 where name='jimmy2';進行對比,結果以下所示:

 

 

3.在已有表中建立主鍵索引

代碼詳細請參考:code/pk2.sql

語法規則:alter table 表名 add primary key(字段名稱)

 

 

執行結果以下:

 

 

有時候咱們在建立主鍵索引的時候,遇到id字段咱們還須要配合設置

整型數據類型的自增加,這時可使用如下語法在已有的表中進行創建

語法規則:Alter table 表名 modify 字段名 字段類型 auto_increment

 

 

執行後,效果以下:

 

 

 

4.刪除表中的主鍵索引

代碼詳細請參考:code/pk3.sql

語法規則:Alter table 表名 drop primary key;

主鍵刪除的詳細步驟:

1)主鍵含有自動增加的特性,須要首先刪除自增加的屬性,不然就會報錯,以下圖所示:

 

 

執行效果以下:

 

 

2)使用Alter table語句修改去除主鍵字段的自動增加屬性,以下圖所示:

 

 

執行結果以下:

 

 

3)使用刪除主鍵的語法規則對主鍵進行刪除.

 

 

執行結果:

 

 

.惟一性索引

惟一索引的原則和場景:

在開發當中,有時咱們在網站使用用戶名進行註冊須要對用戶進行惟一性約束,這時惟一性索引就能夠起到約束的做用,同時惟一索引也能提升數據查找的速度,所以惟一性索引在開發中使用十分普遍。

1.建立惟一性索引

代碼詳細請參考:code/unique1.sql

語法規則:create unique index 索引的名稱 on 表名(字段名稱)

 

 

執行效果以下:

 

 

 

插入一些數據測試惟一索引的約束性:

添加一個username爲tommy的數據進行測試,效果和步驟以下:

1次插入:

 

 

2次插入:

 

 

以上例子給咱們的啓示是能夠在註冊用戶的使用多用惟一性因此進行惟一約束。

使用explain執行計劃查看惟一性索引是否會被使用上:

執行命令:

 

 

2.刪除惟一索引

代碼詳細請參考:code/unique2.sql

語法規則: alter table 表名 drop index 索引的名稱

 

 

執行結果以下:

 

 

 

3.惟一性索引的注意事項

代碼詳細請參考:code/unique3.sql

 

1.在惟一索引當中,null是能夠重複的

 

 

若是重複插入null值結果以下:

 

 

發覺惟一性索引對NULL值不起任何的約束做用,這個是惟一性索引的缺點

2.在惟一索引當中空字符串是不能重複的

 

 

重複插入空字符串進行測試的結果以下:

 

 

 

發覺以上惟一性索引的特性後,咱們能夠把users表修改爲爲如下形式,把惟一性索引在該應用場合中使用主鍵進行替代,查看效果:

 

 

 

執行結果以下:

 

 

面試題:惟一索引和主鍵的區別是什麼?

惟一性索引能夠插入NULL值,但對NULL不起任何的約束做用,惟一性因此對空串能夠插入一次但對空串起惟一性約束做用,主鍵不能夠插入NULL值,空串也能夠插入一次而且起惟一性的約束做用,但主鍵多用於id列,通常是用int的形式比較多,因此在註冊的時候,咱們能夠常使用使用惟一索引而省略id的主鍵索引,以上只是一個參考而不是一個標準.

.普通索引

普通索引的原則和場景:

在開發當中,若是咱們僅僅是爲了提高查詢的效率但不須要用到任何的約束性行爲,那麼就可使用普通索引

1.建立普通索引

代碼詳細請參考:code/normal.sql

建立表和數據以下:

 

 

若是這時不對cake_name字段進行索引的建立,那麼就會產生以下explain執行結果:

 

 

發覺用戶若是按蛋糕名稱進行搜索,那麼就會產生全表掃描,整個效率就太差了。可是咱們又必須不能對cake_name進行惟一索引的約束,這時普通索引的應用場景就出現了。

語法規則:create index 索引名稱 on 表名稱(字段名稱)

 

 

執行效果以下:

 

 

在表具有數據記錄後再建立其實對錶的數據發生任何的改變,效果以下:

 

 

查看建表的結構以下:

 

 

使用explain執行計劃查看普通索引是否會被使用上:

 

 

查詢tbl_yes的表結構以下:

 

 

創建普通索引就算數據有5千多萬條查詢的速度依然能夠很快,只要索引能夠被使用上便可

2.刪除普通索引

語法規則: alter table 表名 drop index 索引的名稱

 

 

執行結果以下:

 

 

 

.全文索引

1.like查詢的索引原則

代碼詳細請參考:code/like.sql

若是咱們須要查看articles_like表中title字段含有mysql關鍵字的數據記錄,那麼咱們能夠建立如下的實驗步驟:

1步:創建articles_like表,而且把title字段設置爲普通索引

 

 

2步:爲articles_like表插入一些測試數據

 

 

執行結果以下:

 

 

3步:咱們使用如下數據庫like語句查詢標題中含有mysql關鍵字的數據庫記錄

使用命令:select * from articles_like where title like '%mysql%';

執行效果以下:

 

 

咱們的title字段是有索引的,是一個普通索引tit,可是這時使用like進行模糊搜索,這個索引是否能夠被使用上呢?

 

4步:使用explain執行計劃查看like語句是否使用到索引

使用命令: explain select * from articles_like where title like '%mysql%';

 

 

發覺like語句使用不了索引,緣由就在於在MySql數據庫中,若是使用like條件語句當中%

出如今查詢關鍵字以前,那麼將沒法使用到索引。因此如下狀況都是不可能使用到索引的:

①select * from articles_like where title like '%mysql%';

②select * from articles_like where title like '%mysql';

 

 

若是把%放在查詢關鍵字以後,那麼就有可能使用上索引,可是這個只是可能性比較高罷了,而不是100%可使用上的.

如下狀況like有可能用得索引,但搜索出來結果不是你想要的:

使用命令: explain select * from articles_like where title like 'mysql%';

執行結果以下:

 

 

若是%號出如今搜索關鍵字以後,那麼like是可使用關鍵字的,然而查詢的結果是會丟失記錄的:

 

 

可是若是咱們真的須要使用到索引,有必須保證查詢結果的完整性,那麼咱們應該怎麼辦呢?

全文索引應運而生.

2.全文索引(FullText)

全文索引是爲取代Like而生,然而mysql自帶的全文因此不支持中文.通常人會使用sphinx+coreseek詞庫來代替它,這個主題咱們會在第3天的時候着重講解

全文索引的原則和場景:

全文索引能很好取代like的查詢,且功能比like強大,但MySql自帶的全文索引FullText在MySql5.6如下的版本並不支持中文,而MySql5.6的數據庫版本使用的用戶不多.所以MySql自帶的全文索引在真正的大型網站開發當中會被Sphinx這個第3方的工具所取代,但自帶的全文索引可使用在一些英文的小型網站當中。

代碼詳細請參考:code/fulltext.sql

若是咱們須要查看articles表中title或者body字段含有database關鍵字的數據記錄,那麼咱們若是咱們要知足以上的要求,就必須使用全文索引

1)建立全文索引

語法規則: fulltext(一個或者多個字段名稱)

注意:通常使用fulltext的時候不多使用一個字段做爲全文索引,由於使用給一個字段全文索引的意義就失去了

 

 

執行結果以下:

 

 

2)articles表插入測試數據

 

 

執行結果以下:

 

 

 

3)全文索引的布爾模式查詢原則

語法規則:match(全文索引的字段列) against( +關鍵字 in boolean mode)

①查看articles表中title或者body字段含有database關鍵字的數據記錄

使用命令:

 

 

執行結果以下:

 

 

②查看articles表中title或者body字段含有mysql關鍵字的數據記錄

使用命令:

 

 

結果以下:

 

 

發覺以上的查詢沒有成功,正常來講應該查詢出6條記錄,可是爲何一條也查不出來的呢?緣由是全文索引實際上是根據算法生成的因此,支持一種叫布爾查詢的模式,所以若是不使用布爾查詢那麼就有可能查詢的結果不許確,所以使用全文索引必須使用布爾查詢模式,使用布爾查詢模式修改上面的查詢語句以下所示:

 

 

執行結果以下所示,發覺查詢正確了:

 

 

咱們發覺全文索引其實能夠完成like的功能,可是它會使用到索引嗎?

使用explain查看全文索引是否有使用到索引:

 

 

 

執行explain語句那麼發覺fulltext索引是能夠被用上,也就是說Like之後你能夠不要使用了,like是能夠徹底使用fulltext來取代的,可是fulltext不支持中文,因此只能應用在英文網站當中,若是但願使用中文的全文因此必須使用第三方工具sphinx+coreseek

十一.MySql的查詢緩存機制

1.查詢緩存機制的概述

mysql全部數據查詢都是實時的過程,無論一次查詢數據是否有找到,那麼數據庫的編譯器都必須在硬盤中作一次數據的查找響應,原理以下所示:

 

 

Mysql提供了一個機制,就是開啓一個叫Qcache的空間緩存,這個緩存空間存在Mysql編譯器內存當中,有一個用戶發起了一次請求編譯器會判斷當前是否已經發起過,若是發起過,那麼編譯器將不會繼續在硬盤當中作出查找的響應,而是把Qcache當中的結果進行返回,若是用戶發起的請求是第一次的發起,那麼mysql依然會從硬盤當中查找數據,可是同時也會把查找結果保存到Qcache空間當中,準備下一次查詢響應,其原理以下所示:

 

 

2.開啓Mysql的查詢緩存

開啓Mysql查詢緩存就是開啓編譯器中的Qcache空間,這個空間默認的狀況下以字節的大小來計算空間的大小,因此咱們須要使用子字節換算來開啓Qcache空間的大小

 

1k = 1024字節

1M = 1024k = 1024 * 1024字節

若是但願表示一個64M的字節大小,那麼咱們能夠換算成爲如下形式公式:

64M = 64 *1024 * 1024字節

開啓MySql查詢緩存的語法格式以下:

set global query_cache_size = 字節大小

需求1:開啓64M的查詢緩存空間(Qcache),代碼以下:

set global query_cache_size = 64 *1024*1024

若是沒有開啓查詢緩存時,使用select語句查詢tbl_no的username=itcast的信息記錄以下所示:

1次查詢以下,用時17.47sec:

 

 

2次查詢以下,用時14.57sec,雖然有所提高,可是並不穩定,也不夠理想

 

 

 

這時咱們使用查詢緩存機制,開啓一個64M的Qcache空間,以下所示:

 

 

開啓成功後,咱們從新對tbl_no表username=itcast進行查詢

 

1次查詢:因爲第1次查詢Qcache並無任何的記錄,因此mysql會從硬盤中查找

耗時:14.44sec

 

 

2次查詢:因爲第2次查詢時Qcache已經記錄當前的查詢結果,所以mysql不會去硬盤中查找數據,直接從Qcache當中返回數據,所以耗時接近0秒甚至達到0秒

 

 

假設這時咱們換一個查詢條件,查詢username=itheima的信息以下:

1次查詢:發覺這時又沒有緩存的結果,由於這是第1次查詢,耗時16.88sec

 

 

2次查詢,發覺耗時接近0秒甚至達到0秒,查詢緩存的開啓就會讓第1次查詢很慢以後都會很快,因此達到必定的優化過程

 

 

 

查詢緩存的缺點是:若是查詢緩存的累積空間達到64M的上限,那麼mysqld就會自動釋放Qcache空間,使得原來緩存消失,而且開啓過多的Qcache空間會致使mysql編譯器內存空間被佔用過多,所以後來有人使用Memcache和redis進行取代,可是若是你的數據不算很是多,那麼使用查詢緩存是很是值得,由於查詢緩存的開啓方式和使用方式很是的簡單

3.關閉mysql的查詢緩存

關閉mysql的查詢緩存有兩種方法:

1)重啓mysqld服務,使用service mysqld restart

2)使用命令: set global query_cache_size = 0 (建議使用該方法)

 

 

關閉以後,查詢查詢username=itcast的信息以下:

 

 

發覺查詢緩存消失,數據查詢從新開始變慢

4.查看查詢緩存是否已經開啓

有時候咱們須要直到這個查詢緩存是否已經開啓,咱們可使用如下命令進行查看:

show variables like '%query_cache_size%'

 

 

若是開啓了查詢緩存,那麼查詢結果以下:

 

 

 

十二.Mysql的慢查詢日誌

1.慢查詢日誌的概述

在開發當中,有時候咱們但願可以捕捉到慢操做的相關具體命令,那麼這時咱們就須要使用慢查詢日誌(query_slow_logs),然而慢查詢日誌不僅是記錄select語句的慢操做,其餘的語句如:insert update delete若是慢的話也會被日誌所記錄

 

慢查詢日誌有如下重要的函數(命令):

#表示當前MySql的認爲慢操做的時間

show variables like 'long_query_time'  

 

 

mysql默認狀況下認爲達到10秒鐘的操做纔算慢,這就與8秒原則相矛盾了,所以咱們須要調整這個long_query_time的時間,根據本身的喜歡認爲怎麼樣纔算慢去調整,通常調整爲2秒鐘

#顯示當前MySql的慢查詢日誌相關選項

show variables like '%slow%';

 

 

#顯示當前MySql的慢操做總數

show status like 'Slow_queries';

 

 

 

 

 

2.開啓慢查詢日誌

若是但願開啓慢查詢日誌,咱們就必需要在Mysql配置文件中打開對應的配置選項,Mysql的配置文件存放在/etc/my.cnf當中,使用vim打開/etc/my.cnf

 

 

內容以下所示:

 

 

咱們須要迅速找到如下幾項:

 

 

修改以上3項內容以下所示:

 

 

保存並退出(:x),而後重啓mysqld服務

 

 

若是重啓沒有報錯,就表明配置選項設置成功,退出mysql登陸從新登陸,重看相關選項

 

 

 

 

 

 

而後咱們檢查配置無誤後,咱們到/var/lib/mysql目錄下查看,發覺有如下文件:

 

 

而後咱們使用一個超過2秒鐘的慢查詢語句,以下所示:

 

 

這時咱們打開/var/lib/mysql/myslow.txt文件查看,使用vim打開

 

 

內容以下所示:

 

相關文章
相關標籤/搜索