1. 程式人生 > >一.mysql優化

一.mysql優化

並且 網絡優化 聯合 適用場景 哪些 uniq -- res ini

一.mysql優化

1.網站請求走向分析優化的方面

需要優化的地方:

a:網絡優化,服務器硬件方面,CDN加速(訪問離用戶最近一臺服務器獲取資源文件(jquery,js))

b:頁面靜態化處理,訪問速度更快

c:php代碼本身需要優化(需要自身經驗的積累)

d:使用memcache,redis減輕數據庫的壓力,減少磁盤的i/o開銷

e:mysql本身的優化

f:mysql架構(讀寫分離,主從復制)

2.mysql的優化的方向

存儲層:選擇合適的存儲引擎,選擇適當的列類型

設計層:給數據表建立合適的索引,滿足表的三範式(逆範式)

sql層:優化更快的sql語句

mysql架構層:mysql讀寫分離

二.數據表的引擎

1.介紹

不同的數據庫引擎有不同的數據結構,也有不同的功能,如:innodb引擎支持事務(ACID)的操作

ACID解釋:

原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation,又稱獨立性)、持久性(Durability)

2

2.數據表引擎

2-1.查看數據表支持引擎種類

2-2.數據表引擎的區別

這裏重點說myisam引擎和innodb引擎的區別(企業基本使用者兩種引擎)

總結innodb和myisam引擎的區別:

①innodb引擎支持事務(ACID特性),myisam不支持

②myisam支持表鎖(對某一行進行編輯.

會鎖住整個表,不適合並發高的網站)

innodb引擎支持行鎖(對某一行操作,不會阻塞其他行的操作)

③myisam引擎支持全文索引(只對英文有效),innodb引擎不支持

後面使用sphinx(斯芬克斯)中文搜索引擎技術

④innodb支持外鍵,myisam不支持(很少使用,一般建立一個額外的字段和其他表關聯)

2-3.myisam和innodb引擎在生產環境的適用場景

①適合於網站主要是讀寫的,業務不高的網站.如:bbs,blog網站

②要求一致性較高的網站(依據事務特性),用innodb引擎

③並發量高的網站建議使用innodb引擎(主要是鎖機制影響)

企業常見mysql引擎的面試:

1.mysql有哪些引擎,區別在哪裏?

:見上文

2.如何選擇合適的存儲引擎

:一般使用innodb引擎,因為它支持事務操作,對業務處理場景要求較高,使用於並發量高的網站.一句話:使用innodb引擎

2-4.myisam引擎和innodb引擎插入數據的對比

第一步:建立兩個表,一個myisam,一個innodb引擎

第二步:給表插入相同的數據(不按照主鍵順序插入)

第三步:查詢各個引擎的數據

問題:如果需要大批量的數據插入,用什麽引擎?

:用myisam引擎,因為插入數據的時候,不需要按照主鍵順序排列,性能更高.(相對而言)

2-5.myisam引擎和innodb引擎生成數據表的方式

結論:

建立一個myisam引擎表的時候,會生成三個文件:

表名.frm:表的結構文件

表名.MYD:表的數據文件

表名.MYI:表的索引文件

建立一個innodb引擎表的時候,會生成一個文件:

表名.frm:表的結構文件

其數據文件和索引文件存放在mysql安裝目錄/data/目錄下面的ibdata文件中.

2-6.引擎的數據結構(B-tree,了解即可)

特別註意:

主鍵就是一種索引(主鍵),索引就是一種數據結構

①myisam引擎(非聚合結構)

②innodb引擎(聚合結構)(聚簇結構)

結輪:問題,如果需要大批量的查詢數據庫,使用innodb,因為不需要做回行操作(相對myisam而言)

註意:因為不管是innodb還是mysiam引擎,其本質都是要操作我們的磁盤,都是需要磁盤i/o開銷(mysql最大的瓶頸就是在磁盤i/o方面),

所以如果某個數據頻繁訪問,我們可以先把數據緩存在memcache中去,下次直接請求memcache中的數據,可以減輕mysql數據庫的壓力.

2-7.數據的備份

①數據庫備份和還原的指令

②備份操作

a:先創建一個數據庫,並且在建立一個數據表

mysqldump -u用戶名 -p密碼 數據庫名>備份的路徑(後綴名為sql)

備份的文件的如下:

③還原

刪除之前的數據庫,在建立一個數據庫:

mysql -u用戶名 -p密碼 數據庫名<備份的路徑(後綴名為sql)

也可以通過mysql終端的source指令進行還原:

也可以通過mysql可視化工具來完成:

三.數據列類型的優化

1.選擇列類型的原則

decimal(8,2):存儲跟錢有關的數據,8表示長度,2小數點後面保留兩位

能用char的盡量用char,固定長度的列處理數據的速度更快.

mysql幫助指令, help 命令:

學習一個技能的時候,需要掌握獲取這個知識的過程

2.存儲數據的範例

存儲性別:tinyint,女-1, 男-0, 保密-2

存儲標題:空間不確定使用varchar,如果確定數據長度範圍10-20,建議使用char(20)

存儲時間:int或date

建議使用int類型來存儲時間,原因可以方便根據時間戳查詢,方便處理,處理更加靈活.

存儲文章:用text

存儲ip:用整數int(整數數據類型處理速度要快於字符串數據類型)

$_SERVER[‘REMOTE_ADDR’]=’192.168.148.188’

mysql中ip地址和整數互相轉化的方法:

php中ip地址和整數互相轉化的方法:

四.數據表的三範式

1.第一範式(1NF)

就是要保證每個字段的原子性,不可以在進行分割

有個用戶表:

id name age address

1 小妹 18 廣東省廣州市白雲區**街道12

1 小美 20 廣東省深圳保安區**街道15

以上的address字段可以再進行分割,沒有滿足第一範式,我們可以對其分割多個字段來存儲

id name age province city area

1 小妹 18 廣東省 廣州市 白雲區**街道12

1 小美 20 廣東省 深圳保 安區**街道15

2.第二範式(2NF)

在滿足第一範式的前提下,要保證每條記錄的唯一性,解決辦法,給表設置一個主鍵字段即可

id name age province city area

1 小妹 18 廣東省 廣州市 白雲區**街道12

2 小美 20 廣東省 深圳保 安區**街道15

3.第三範式(3NF)

在滿足第二範式的前提下,保證每條記錄只存儲一種類型的數據,為了解決數據的冗余

學生表為例:

id name age classid classname teacher

1 小妹 18 2 工程系 李老師

2 小美 20 3 美術系 許老師

3 小洪 22 2 工程系 李老師

4 小虎 21 2 工程系 李老師

可以將以上的表設計為兩張表來存儲,一張學生表,一張系表

學生表:

id name age classid

1 小妹 18 2

2 小美 20 3

3 小洪 22 2

4 小虎 21 2

系表:

id classname teacher

2 工程系 李老師

3 美術系 許老師

4.逆範式

我們一般建表基本都是滿足三範式,但是有時候為了方便業務邏輯的處理,為了更好維護,我們可以適當的違反三範式,我們把這種設計稱之”逆範式”.

五.索引

1.索引的介紹

生活上面:公交站牌,書本的目錄

索引就是一種數據結構,在文件中已經是按指針排好序了,主要提高我們的查詢數據的速度.

註意的地方:

一個表中的索引不是越多越好,適當即可,索引越多對我們的更新,刪除效率會有所降低,

一個網站百分之70%-80%都是select操作,其他的都是我們的修改操作

2.索引的分類

①主鍵索引:一個表只能有一個主鍵索引,但是可以有復合主鍵索引.

②普通索引:一個表可以有多個普通索引.

③唯一索引:一個表可以有多個唯一索引,就是字段的值不可以相同

提示:一般使用程序控制一個字段的唯一性;

④全文索引:只有myisam引擎才有(mysql5.6版本後也有),只對英文有效,對中文索引采用sphinx來操作

⑤復合(多列,聯合)索引:由多個字段組成的索引.

3.索引的操作

3-1.索引的創建

創建索引一般都是在建表語句中建立好,或者是通過alter修改語句添加索引,還有可以通過create語句也可以添加索引

a:建表的時候創建索引

#建表創建索引

create table t_key(

id int not null auto_increment,

title varchar(30) not null default ‘‘,

email varchar(30) not null default ‘‘,

addtime date ,

primary key(id),

key title_key(title),

unique key email_uni_key(email)

);

b:通過alert語句建立索引

3-2.刪除索引

alter table tablename drop primary key:刪除主鍵

alter table tablename drop key key_name:刪除普通索引,唯一索引

查看建表語句:

刪除操作:

4.使用蠕蟲復制大數據表,進行有無所索引測試對比

至於為什麽使用索引查詢這麽快,怎麽知道?

可以在select前面加一個explain select ....

獲取加一個desc select ............

5.explain執行計劃

5-1.介紹

5-2.explain具體操作

針對有問題的sql語句進行優化,把no_index建立一個普通索引:

建立索引之後再次查詢測試結果:

6.使用索引的原則

①經常出現在where條件後面作為查詢條件的字段

②不要對索引字段使用運算或函數處理

③ like原則

like “aaa%” :可以使用到索引

like “%aaa%” :可以使用到索引

進行測試:

第一步:給title字段建立普通索引:

第二步:進行like模糊查詢測試

④對於or查詢,or前後的字段都必須是索引,如果其中一個不是,那麽都將使用不到索引查詢

⑤復合索引的最左原則

只要使用到復合索引的最左邊的字段,那麽後面的字段才會使用到

key(a,b,c) :給a,b,c三個字段設置復合索引

可以使用到索引的組合:

where a=’’

where a=’’ and b=’’

where a=’’ and b=’’ and c=”

查詢測試:

六.針對sql語句的優化

①優化order by 語句

一句話,盡可能的使用到主鍵索引進行查詢

②針對limit語句優化

select * from t_big limit 100000,10 :

limit 1400000,20 ---->3.11s

limit 1490000,20 ---->3.30s

limit的起始位置越大,那麽耗費查詢時間越長,

解決辦法:使用覆蓋索引+延時關聯技巧

覆蓋索引:當查詢到的字段恰好是索引的字段

覆蓋索引+延時關聯技巧:

select * from t_big limit 1490000,20 ---->3.30s

select t1.* from t_big as t1 inner join (select id as idd from t_big limit 1490000,20) as t2

where t2.idd=t1.id;

select t1.* from t_big as t1 inner join (select id as idd from t_big limit 1590000,20) as t2

where t2.idd=t1.id;

結論:時間比之前耗費了更短時間.

七.慢查詢日誌

1.介紹

我們程序員可以定義一個時間界限(3s),只要有sql語句的執行時間超過我們所規定的時間界限,

就會被記錄在日誌文件裏面,我們就可以在日誌文件中找出這些有問題(所規定的時間界限)的sql語句,從而優化它.

2.開啟慢日誌查詢

第一步:開啟慢查詢;

第二步:去mysql配置文件my.ini添加以下兩行:

重啟mysql服務器:

第三步:進行sql語句測試:

提示:在以後的開發建立大家開啟慢日誌查詢,定義一個時間界限,時隔一段時間就去查看慢日誌文件,看有沒有比較慢的sql語句,從而優化它.

八.profile工具

1.介紹

使用profile工具,可以知道一條sql語句所花費的時間的具體情況,花費在哪些地方.

2.具體操作

第一步:開啟profiling

第二步:進行sql語句測試

第三步:使用show profiles:查看所有開啟profiling工具後的所有的sql語句

第四步:查看某一條sql語句所花費的時間

一.mysql優化